public inbox for [email protected]
help / color / mirror / Atom feedPOC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
94+ messages / 19 participants
[nested] [flat]
* POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
@ 2014-12-25 21:23 Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Alex Shulgin @ 2014-12-25 21:23 UTC (permalink / raw)
To: pgsql-hackers
Trent Shipley <[email protected]> writes:
> On Friday 2007-12-14 16:22, Tom Lane wrote:
>> Neil Conway <[email protected]> writes:
>> > By modifying COPY: COPY IGNORE ERRORS or some such would instruct COPY
>> > to drop (and log) rows that contain malformed data. That is, rows with
>> > too many or too few columns, rows that result in constraint violations,
>> > and rows containing columns where the data type's input function raises
>> > an error. The last case is the only thing that would be a bit tricky to
>> > implement, I think: you could use PG_TRY() around the InputFunctionCall,
>> > but I guess you'd need a subtransaction to ensure that you reset your
>> > state correctly after catching an error.
>>
>> Yeah. It's the subtransaction per row that's daunting --- not only the
>> cycles spent for that, but the ensuing limitation to 4G rows imported
>> per COPY.
>
> You could extend the COPY FROM syntax with a COMMIT EVERY n clause. This
> would help with the 4G subtransaction limit. The cost to the ETL process is
> that a simple rollback would not be guaranteed send the process back to it's
> initial state. There are easy ways to deal with the rollback issue though.
>
> A {NO} RETRY {USING algorithm} clause might be useful. If the NO RETRY
> option is selected then the COPY FROM can run without subtransactions and in
> excess of the 4G per transaction limit. NO RETRY should be the default since
> it preserves the legacy behavior of COPY FROM.
>
> You could have an EXCEPTIONS TO {filename|STDERR} clause. I would not give the
> option of sending exceptions to a table since they are presumably malformed,
> otherwise they would not be exceptions. (Users should re-process exception
> files if they want an if good then table a else exception to table b ...)
>
> EXCEPTIONS TO and NO RETRY would be mutually exclusive.
>
>
>> If we could somehow only do a subtransaction per failure, things would
>> be much better, but I don't see how.
Hello,
Attached is a proof of concept patch for this TODO item. There is no
docs yet, I just wanted to know if approach is sane.
The added syntax is like the following:
COPY [table] FROM [file/program/stdin] EXCEPTIONS TO [file or stdout]
The way it's done it is abusing Copy Both mode and from my limited
testing, that seems to just work. The error trapping itself is done
using PG_TRY/PG_CATCH and can only catch formatting or before-insert
trigger errors, no attempt is made to recover from a failed unique
constraint, etc.
Example in action:
postgres=# \d test_copy2
Table "public.test_copy2"
Column | Type | Modifiers
--------+---------+-----------
id | integer |
val | integer |
postgres=# copy test_copy2 from program 'seq 3' exceptions to stdout;
1
NOTICE: missing data for column "val"
CONTEXT: COPY test_copy2, line 1: "1"
2
NOTICE: missing data for column "val"
CONTEXT: COPY test_copy2, line 2: "2"
3
NOTICE: missing data for column "val"
CONTEXT: COPY test_copy2, line 3: "3"
NOTICE: total exceptions ignored: 3
postgres=# \d test_copy1
Table "public.test_copy1"
Column | Type | Modifiers
--------+---------+-----------
id | integer | not null
postgres=# set client_min_messages to warning;
SET
postgres=# copy test_copy1 from program 'ls /proc' exceptions to stdout;
...
vmstat
zoneinfo
postgres=#
Limited performance testing shows no significant difference between
error-catching and plain code path. For example, timing
copy test_copy1 from program 'seq 1000000' [exceptions to stdout]
shows similar numbers with or without the added "exceptions to" clause.
Now that I'm sending this I wonder if the original comment about the
need for subtransaction around every loaded line still holds. Any
example of what would be not properly rolled back by just PG_TRY?
Happy hacking!
--
Alex
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Attachments:
[text/x-diff] 0001-poc-copy-from-.-exceptions-to.patch (37.7K, ../../[email protected]/2-0001-poc-copy-from-.-exceptions-to.patch)
download | inline diff:
From 50f7ab0a503a0d61776add8a138abf2622fc6c35 Mon Sep 17 00:00:00 2001
From: Alex Shulgin <[email protected]>
Date: Fri, 19 Dec 2014 18:21:31 +0300
Subject: [PATCH] POC: COPY FROM ... EXCEPTIONS TO
---
contrib/file_fdw/file_fdw.c | 4 +-
src/backend/commands/copy.c | 251 +++++++++++++++++++++++++++++---
src/backend/parser/gram.y | 26 +++-
src/bin/psql/common.c | 14 +-
src/bin/psql/copy.c | 119 ++++++++++++++-
src/bin/psql/settings.h | 1 +
src/bin/psql/startup.c | 1 +
src/bin/psql/tab-complete.c | 12 +-
src/include/commands/copy.h | 3 +-
src/include/nodes/parsenodes.h | 1 +
src/include/parser/kwlist.h | 1 +
src/interfaces/ecpg/preproc/ecpg.addons | 2 +-
12 files changed, 396 insertions(+), 39 deletions(-)
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
new file mode 100644
index 5a4d5aa..0df02f7
*** a/contrib/file_fdw/file_fdw.c
--- b/contrib/file_fdw/file_fdw.c
*************** fileBeginForeignScan(ForeignScanState *n
*** 624,629 ****
--- 624,630 ----
cstate = BeginCopyFrom(node->ss.ss_currentRelation,
filename,
false,
+ NULL,
NIL,
options);
*************** fileReScanForeignScan(ForeignScanState *
*** 697,702 ****
--- 698,704 ----
festate->cstate = BeginCopyFrom(node->ss.ss_currentRelation,
festate->filename,
false,
+ NULL,
NIL,
festate->options);
}
*************** file_acquire_sample_rows(Relation onerel
*** 1030,1036 ****
/*
* Create CopyState from FDW options.
*/
! cstate = BeginCopyFrom(onerel, filename, false, NIL, options);
/*
* Use per-tuple memory context to prevent leak of memory used to read
--- 1032,1038 ----
/*
* Create CopyState from FDW options.
*/
! cstate = BeginCopyFrom(onerel, filename, false, NULL, NIL, options);
/*
* Use per-tuple memory context to prevent leak of memory used to read
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
new file mode 100644
index 08abe14..4f59c63
*** a/src/backend/commands/copy.c
--- b/src/backend/commands/copy.c
*************** typedef enum EolType
*** 96,102 ****
typedef struct CopyStateData
{
/* low-level state data */
! CopyDest copy_dest; /* type of copy source/destination */
FILE *copy_file; /* used if copy_dest == COPY_FILE */
StringInfo fe_msgbuf; /* used for all dests during COPY TO, only for
* dest == COPY_NEW_FE in COPY FROM */
--- 96,103 ----
typedef struct CopyStateData
{
/* low-level state data */
! CopyDest copy_src; /* type of copy source */
! CopyDest copy_dest; /* type of copy destination */
FILE *copy_file; /* used if copy_dest == COPY_FILE */
StringInfo fe_msgbuf; /* used for all dests during COPY TO, only for
* dest == COPY_NEW_FE in COPY FROM */
*************** typedef struct CopyStateData
*** 105,110 ****
--- 106,114 ----
int file_encoding; /* file or remote side's character encoding */
bool need_transcoding; /* file encoding diff from server? */
bool encoding_embeds_ascii; /* ASCII can be non-first byte? */
+ bool ignore_exceptions; /* should we trap and ignore exceptions? */
+ FILE *exc_file; /* file stream to write erroring lines to */
+ uint64 exceptions; /* total number of exceptions ignored */
/* parameters from the COPY command */
Relation rel; /* relation to copy to or from */
*************** typedef struct CopyStateData
*** 112,117 ****
--- 116,122 ----
List *attnumlist; /* integer list of attnums to copy */
char *filename; /* filename, or NULL for STDIN/STDOUT */
bool is_program; /* is 'filename' a program to popen? */
+ char *exc_filename; /* filename for exceptions or NULL for STDOUT */
bool binary; /* binary format? */
bool oids; /* include OIDs? */
bool freeze; /* freeze rows on loading? */
*************** SendCopyBegin(CopyState cstate)
*** 347,352 ****
--- 352,366 ----
int16 format = (cstate->binary ? 1 : 0);
int i;
+ /*
+ * Check if we might need to stream exceptions to the frontend. If
+ * so, this must be a "COPY FROM file/program EXCEPTIONS TO STDOUT".
+ *
+ * We need to create the frontend message buffer now.
+ */
+ if (cstate->ignore_exceptions)
+ cstate->fe_msgbuf = makeStringInfo();
+
pq_beginmessage(&buf, 'H');
pq_sendbyte(&buf, format); /* overall format */
pq_sendint(&buf, natts, 2);
*************** ReceiveCopyBegin(CopyState cstate)
*** 388,404 ****
{
/* new way */
StringInfoData buf;
int natts = list_length(cstate->attnumlist);
int16 format = (cstate->binary ? 1 : 0);
int i;
! pq_beginmessage(&buf, 'G');
pq_sendbyte(&buf, format); /* overall format */
pq_sendint(&buf, natts, 2);
for (i = 0; i < natts; i++)
pq_sendint(&buf, format, 2); /* per-column formats */
pq_endmessage(&buf);
! cstate->copy_dest = COPY_NEW_FE;
cstate->fe_msgbuf = makeStringInfo();
}
else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
--- 402,428 ----
{
/* new way */
StringInfoData buf;
+ char msgid = 'G'; /* receiving from client only */
int natts = list_length(cstate->attnumlist);
int16 format = (cstate->binary ? 1 : 0);
int i;
! /*
! * Check if we also need to pipe exceptions back to the frontend.
! */
! if (cstate->ignore_exceptions && cstate->exc_filename == NULL)
! {
! msgid = 'W'; /* copying in both directions */
! cstate->copy_dest = COPY_NEW_FE;
! }
!
! pq_beginmessage(&buf, msgid);
pq_sendbyte(&buf, format); /* overall format */
pq_sendint(&buf, natts, 2);
for (i = 0; i < natts; i++)
pq_sendint(&buf, format, 2); /* per-column formats */
pq_endmessage(&buf);
! cstate->copy_src = COPY_NEW_FE;
cstate->fe_msgbuf = makeStringInfo();
}
else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
*************** ReceiveCopyBegin(CopyState cstate)
*** 409,415 ****
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY BINARY is not supported to stdout or from stdin")));
pq_putemptymessage('G');
! cstate->copy_dest = COPY_OLD_FE;
}
else
{
--- 433,439 ----
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY BINARY is not supported to stdout or from stdin")));
pq_putemptymessage('G');
! cstate->copy_src = COPY_OLD_FE;
}
else
{
*************** ReceiveCopyBegin(CopyState cstate)
*** 419,425 ****
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY BINARY is not supported to stdout or from stdin")));
pq_putemptymessage('D');
! cstate->copy_dest = COPY_OLD_FE;
}
/* We *must* flush here to ensure FE knows it can send. */
pq_flush();
--- 443,449 ----
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("COPY BINARY is not supported to stdout or from stdin")));
pq_putemptymessage('D');
! cstate->copy_src = COPY_OLD_FE;
}
/* We *must* flush here to ensure FE knows it can send. */
pq_flush();
*************** CopySendChar(CopyState cstate, char c)
*** 472,486 ****
appendStringInfoCharMacro(cstate->fe_msgbuf, c);
}
static void
CopySendEndOfRow(CopyState cstate)
{
StringInfo fe_msgbuf = cstate->fe_msgbuf;
switch (cstate->copy_dest)
{
case COPY_FILE:
! if (!cstate->binary)
{
/* Default line termination depends on platform */
#ifndef WIN32
--- 496,560 ----
appendStringInfoCharMacro(cstate->fe_msgbuf, c);
}
+ /*
+ * This should be called from PG_CATCH() after switching to appropriate
+ * MemoryContext.
+ */
+ static void
+ CopySendException(CopyState cstate)
+ {
+ ErrorData *error;
+
+ ++cstate->exceptions;
+
+ /*
+ * When reading from the frontend, we reuse the current line held in the
+ * message buffer to send the exception line back, otherwise we need to
+ * copy the line over from the line buffer.
+ */
+ if (cstate->copy_src == COPY_FILE)
+ CopySendData(cstate, cstate->line_buf.data, cstate->line_buf.len);
+
+ /* this flushes the message buffer */
+ CopySendEndOfRow(cstate);
+
+ error = CopyErrorData();
+ FlushErrorState();
+
+ /* report error as a harmless notice */
+ ereport(NOTICE,
+ (errmsg("%s", error->message)));
+ FreeErrorData(error);
+ }
+
static void
CopySendEndOfRow(CopyState cstate)
{
StringInfo fe_msgbuf = cstate->fe_msgbuf;
+ FILE *file;
+ bool should_add_newline;
+
+ /* determine where are we writing to */
+ if (cstate->ignore_exceptions)
+ {
+ file = cstate->exc_file;
+ /*
+ * We should only add a newline if we're not sending the frontend what
+ * it has just sent us and in any case we shouldn't do this for binary
+ * copy.
+ */
+ should_add_newline = (cstate->copy_src == COPY_FILE && !cstate->binary);
+ }
+ else
+ {
+ file = cstate->copy_file;
+ should_add_newline = !(cstate->binary);
+ }
switch (cstate->copy_dest)
{
case COPY_FILE:
! if (should_add_newline)
{
/* Default line termination depends on platform */
#ifndef WIN32
*************** CopySendEndOfRow(CopyState cstate)
*** 490,498 ****
#endif
}
! if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
! cstate->copy_file) != 1 ||
! ferror(cstate->copy_file))
{
if (cstate->is_program)
{
--- 564,571 ----
#endif
}
! if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1, file) != 1 ||
! ferror(file))
{
if (cstate->is_program)
{
*************** CopySendEndOfRow(CopyState cstate)
*** 525,531 ****
break;
case COPY_OLD_FE:
/* The FE/BE protocol uses \n as newline for all platforms */
! if (!cstate->binary)
CopySendChar(cstate, '\n');
if (pq_putbytes(fe_msgbuf->data, fe_msgbuf->len))
--- 598,604 ----
break;
case COPY_OLD_FE:
/* The FE/BE protocol uses \n as newline for all platforms */
! if (should_add_newline)
CopySendChar(cstate, '\n');
if (pq_putbytes(fe_msgbuf->data, fe_msgbuf->len))
*************** CopySendEndOfRow(CopyState cstate)
*** 538,544 ****
break;
case COPY_NEW_FE:
/* The FE/BE protocol uses \n as newline for all platforms */
! if (!cstate->binary)
CopySendChar(cstate, '\n');
/* Dump the accumulated row as one CopyData message */
--- 611,617 ----
break;
case COPY_NEW_FE:
/* The FE/BE protocol uses \n as newline for all platforms */
! if (should_add_newline)
CopySendChar(cstate, '\n');
/* Dump the accumulated row as one CopyData message */
*************** CopySendEndOfRow(CopyState cstate)
*** 546,552 ****
break;
}
! resetStringInfo(fe_msgbuf);
}
/*
--- 619,630 ----
break;
}
! /*
! * Avoid resetting the buffer we reused to send the exception line back to
! * the frontend.
! */
! if (!cstate->ignore_exceptions || cstate->copy_src == COPY_FILE)
! resetStringInfo(fe_msgbuf);
}
/*
*************** CopyGetData(CopyState cstate, void *data
*** 567,573 ****
{
int bytesread = 0;
! switch (cstate->copy_dest)
{
case COPY_FILE:
bytesread = fread(databuf, 1, maxread, cstate->copy_file);
--- 645,651 ----
{
int bytesread = 0;
! switch (cstate->copy_src)
{
case COPY_FILE:
bytesread = fread(databuf, 1, maxread, cstate->copy_file);
*************** DoCopy(const CopyStmt *stmt, const char
*** 919,930 ****
PreventCommandIfReadOnly("COPY FROM");
cstate = BeginCopyFrom(rel, stmt->filename, stmt->is_program,
! stmt->attlist, stmt->options);
*processed = CopyFrom(cstate); /* copy from file to database */
EndCopyFrom(cstate);
}
else
{
cstate = BeginCopyTo(rel, query, queryString, relid,
stmt->filename, stmt->is_program,
stmt->attlist, stmt->options);
--- 997,1018 ----
PreventCommandIfReadOnly("COPY FROM");
cstate = BeginCopyFrom(rel, stmt->filename, stmt->is_program,
! stmt->exc_filename, stmt->attlist, stmt->options);
*processed = CopyFrom(cstate); /* copy from file to database */
+ if (cstate->exceptions)
+ ereport(NOTICE,
+ (errmsg("total exceptions ignored: " UINT64_FORMAT,
+ cstate->exceptions)));
EndCopyFrom(cstate);
}
else
{
+ if (stmt->exc_filename != NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("EXCEPTIONS TO not allowed with COPY ... TO"),
+ errhint("see COPY ... FROM")));
+
cstate = BeginCopyTo(rel, query, queryString, relid,
stmt->filename, stmt->is_program,
stmt->attlist, stmt->options);
*************** BeginCopy(bool is_from,
*** 1561,1566 ****
--- 1649,1655 ----
/* See Multibyte encoding comment above */
cstate->encoding_embeds_ascii = PG_ENCODING_IS_CLIENT_ONLY(cstate->file_encoding);
+ cstate->copy_src = COPY_FILE; /* default */
cstate->copy_dest = COPY_FILE; /* default */
MemoryContextSwitchTo(oldcontext);
*************** EndCopy(CopyState cstate)
*** 1608,1613 ****
--- 1697,1708 ----
cstate->filename)));
}
+ if (cstate->exc_filename != NULL && FreeFile(cstate->exc_file))
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not close file \"%s\": %m",
+ cstate->exc_filename)));
+
MemoryContextDelete(cstate->copycontext);
pfree(cstate);
}
*************** CopyFrom(CopyState cstate)
*** 2331,2336 ****
--- 2426,2432 ----
{
TupleTableSlot *slot;
bool skip_tuple;
+ bool depleted;
Oid loaded_oid = InvalidOid;
CHECK_FOR_INTERRUPTS();
*************** CopyFrom(CopyState cstate)
*** 2348,2356 ****
/* Switch into its memory context */
MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
! if (!NextCopyFrom(cstate, econtext, values, nulls, &loaded_oid))
break;
/* And now we can form the input tuple. */
tuple = heap_form_tuple(tupDesc, values, nulls);
--- 2444,2475 ----
/* Switch into its memory context */
MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
! skip_tuple = false;
! depleted = false;
!
! PG_TRY();
! {
! if (!NextCopyFrom(cstate, econtext, values, nulls, &loaded_oid))
! /* can't break right here due to PG_TRY using do/while(0) */
! depleted = true;
! }
! PG_CATCH();
! {
! if (!cstate->ignore_exceptions)
! PG_RE_THROW();
!
! skip_tuple = true;
! MemoryContextSwitchTo(oldcontext);
! CopySendException(cstate);
! }
! PG_END_TRY();
!
! if (depleted)
break;
+ if (skip_tuple)
+ continue;
+
/* And now we can form the input tuple. */
tuple = heap_form_tuple(tupDesc, values, nulls);
*************** CopyFrom(CopyState cstate)
*** 2376,2382 ****
if (resultRelInfo->ri_TrigDesc &&
resultRelInfo->ri_TrigDesc->trig_insert_before_row)
{
! slot = ExecBRInsertTriggers(estate, resultRelInfo, slot);
if (slot == NULL) /* "do nothing" */
skip_tuple = true;
--- 2495,2514 ----
if (resultRelInfo->ri_TrigDesc &&
resultRelInfo->ri_TrigDesc->trig_insert_before_row)
{
! PG_TRY();
! {
! slot = ExecBRInsertTriggers(estate, resultRelInfo, slot);
! }
! PG_CATCH();
! {
! if (!cstate->ignore_exceptions)
! PG_RE_THROW();
!
! slot = NULL;
! MemoryContextSwitchTo(oldcontext);
! CopySendException(cstate);
! }
! PG_END_TRY();
if (slot == NULL) /* "do nothing" */
skip_tuple = true;
*************** CopyFrom(CopyState cstate)
*** 2384,2395 ****
tuple = ExecMaterializeSlot(slot);
}
! if (!skip_tuple)
{
! /* Check the constraints of the tuple */
! if (cstate->rel->rd_att->constr)
ExecConstraints(resultRelInfo, slot, estate);
if (useHeapMultiInsert)
{
/* Add this tuple to the tuple buffer */
--- 2516,2545 ----
tuple = ExecMaterializeSlot(slot);
}
! if (skip_tuple)
! continue;
!
! /* Check the constraints of the tuple */
! if (cstate->rel->rd_att->constr)
{
! PG_TRY();
! {
ExecConstraints(resultRelInfo, slot, estate);
+ }
+ PG_CATCH();
+ {
+ if (!cstate->ignore_exceptions)
+ PG_RE_THROW();
+ skip_tuple = true;
+ MemoryContextSwitchTo(oldcontext);
+ CopySendException(cstate);
+ }
+ PG_END_TRY();
+ }
+
+ if (!skip_tuple)
+ {
if (useHeapMultiInsert)
{
/* Add this tuple to the tuple buffer */
*************** CopyState
*** 2573,2583 ****
--- 2723,2736 ----
BeginCopyFrom(Relation rel,
const char *filename,
bool is_program,
+ const char *exc_filename,
List *attnamelist,
List *options)
{
CopyState cstate;
bool pipe = (filename == NULL);
+ bool ignore_exceptions = (exc_filename != NULL);
+ bool exc_pipe = (exc_filename != NULL && *exc_filename == 0);
TupleDesc tupDesc;
Form_pg_attribute *attr;
AttrNumber num_phys_attrs,
*************** BeginCopyFrom(Relation rel,
*** 2686,2691 ****
--- 2839,2900 ----
cstate->volatile_defexprs = volatile_defexprs;
cstate->num_defaults = num_defaults;
cstate->is_program = is_program;
+ cstate->ignore_exceptions = ignore_exceptions;
+
+ if (ignore_exceptions)
+ {
+ if (exc_pipe)
+ {
+ if (whereToSendOutput == DestRemote)
+ {
+ if (!pipe)
+ SendCopyBegin(cstate);
+ else
+ ; /* handled by ReceiveCopyBegin() call below */
+ }
+ else
+ {
+ cstate->exc_file = stdout;
+ }
+ }
+ else
+ {
+ if (!is_absolute_path(exc_filename))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_NAME),
+ errmsg("relative path not allowed for EXCEPTIONS TO file")));
+
+ if (!pipe)
+ {
+ struct stat stbuf_exc;
+ struct stat stbuf_from;
+
+ /* check if both FROM and EXCEPTIONS TO are the same file */
+ if (stat(exc_filename, &stbuf_exc) == 0 &&
+ stat(filename, &stbuf_from) == 0 &&
+ stbuf_exc.st_dev == stbuf_from.st_dev &&
+ stbuf_exc.st_ino == stbuf_from.st_ino)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_NAME),
+ errmsg("cannot specify the same file for COPY FROM and EXCEPTIONS TO")));
+ }
+ /*
+ * We won't send or receive data via frontend, but we still
+ * need to the buffer for CopySendException() to work with.
+ */
+ cstate->fe_msgbuf = makeStringInfo();
+ }
+
+ cstate->exc_filename = pstrdup(exc_filename);
+ cstate->exc_file = AllocateFile(cstate->exc_filename, PG_BINARY_W);
+ if (cstate->exc_file == NULL)
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not open file \"%s\" for writing: %m",
+ cstate->exc_filename)));
+ }
+ }
if (pipe)
{
*************** NextCopyFrom(CopyState cstate, ExprConte
*** 3019,3025 ****
*/
char dummy;
! if (cstate->copy_dest != COPY_OLD_FE &&
CopyGetData(cstate, &dummy, 1, 1) > 0)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
--- 3228,3234 ----
*/
char dummy;
! if (cstate->copy_src != COPY_OLD_FE &&
CopyGetData(cstate, &dummy, 1, 1) > 0)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
*************** CopyReadLine(CopyState cstate)
*** 3133,3139 ****
* after \. up to the protocol end of copy data. (XXX maybe better
* not to treat \. as special?)
*/
! if (cstate->copy_dest == COPY_NEW_FE)
{
do
{
--- 3342,3348 ----
* after \. up to the protocol end of copy data. (XXX maybe better
* not to treat \. as special?)
*/
! if (cstate->copy_src == COPY_NEW_FE)
{
do
{
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
new file mode 100644
index 6431601..47f2be2
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
*************** static Node *makeRecursiveViewSelect(cha
*** 307,313 ****
%type <defelt> event_trigger_when_item
%type <chr> enable_trigger
! %type <str> copy_file_name
database_name access_method_clause access_method attr_name
name cursor_name file_name
index_name opt_index_name cluster_index_specification
--- 307,313 ----
%type <defelt> event_trigger_when_item
%type <chr> enable_trigger
! %type <str> copy_file_name opt_copy_exceptions
database_name access_method_clause access_method attr_name
name cursor_name file_name
index_name opt_index_name cluster_index_specification
*************** static Node *makeRecursiveViewSelect(cha
*** 561,567 ****
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC
DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
! EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EVENT EXCEPT
EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN
EXTENSION EXTERNAL EXTRACT
--- 561,568 ----
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC
DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
! EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EVENT
! EXCEPT EXCEPTIONS
EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN
EXTENSION EXTERNAL EXTRACT
*************** ClosePortalStmt:
*** 2515,2521 ****
/*****************************************************************************
*
* QUERY :
! * COPY relname [(columnList)] FROM/TO file [WITH] [(options)]
* COPY ( SELECT ... ) TO file [WITH] [(options)]
*
* where 'file' can be one of:
--- 2516,2523 ----
/*****************************************************************************
*
* QUERY :
! * COPY relname [(columnList)] FROM/TO file [EXCEPTIONS TO file]
! * [WITH] [(options)]
* COPY ( SELECT ... ) TO file [WITH] [(options)]
*
* where 'file' can be one of:
*************** ClosePortalStmt:
*** 2534,2540 ****
*****************************************************************************/
CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids
! copy_from opt_program copy_file_name copy_delimiter opt_with copy_options
{
CopyStmt *n = makeNode(CopyStmt);
n->relation = $3;
--- 2536,2543 ----
*****************************************************************************/
CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids
! copy_from opt_program copy_file_name opt_copy_exceptions copy_delimiter
! opt_with copy_options
{
CopyStmt *n = makeNode(CopyStmt);
n->relation = $3;
*************** CopyStmt: COPY opt_binary qualified_name
*** 2543,2548 ****
--- 2546,2552 ----
n->is_from = $6;
n->is_program = $7;
n->filename = $8;
+ n->exc_filename = $9;
if (n->is_program && n->filename == NULL)
ereport(ERROR,
*************** CopyStmt: COPY opt_binary qualified_name
*** 2556,2565 ****
n->options = lappend(n->options, $2);
if ($5)
n->options = lappend(n->options, $5);
! if ($9)
! n->options = lappend(n->options, $9);
! if ($11)
! n->options = list_concat(n->options, $11);
$$ = (Node *)n;
}
| COPY select_with_parens TO opt_program copy_file_name opt_with copy_options
--- 2560,2569 ----
n->options = lappend(n->options, $2);
if ($5)
n->options = lappend(n->options, $5);
! if ($10)
! n->options = lappend(n->options, $10);
! if ($12)
! n->options = list_concat(n->options, $12);
$$ = (Node *)n;
}
| COPY select_with_parens TO opt_program copy_file_name opt_with copy_options
*************** copy_file_name:
*** 2604,2609 ****
--- 2608,2618 ----
| STDOUT { $$ = NULL; }
;
+ opt_copy_exceptions:
+ EXCEPTIONS TO copy_file_name { $$ = ($3 ? $3 : ""); }
+ | /* EMPTY */ { $$ = NULL; }
+ ;
+
copy_options: copy_opt_list { $$ = $1; }
| '(' copy_generic_opt_list ')' { $$ = $2; }
;
*************** unreserved_keyword:
*** 13142,13147 ****
--- 13151,13157 ----
| ENUM_P
| ESCAPE
| EVENT
+ | EXCEPTIONS
| EXCLUDE
| EXCLUDING
| EXCLUSIVE
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
new file mode 100644
index 66d80b5..d308286
*** a/src/bin/psql/common.c
--- b/src/bin/psql/common.c
*************** AcceptResult(const PGresult *result)
*** 388,393 ****
--- 388,394 ----
case PGRES_EMPTY_QUERY:
case PGRES_COPY_IN:
case PGRES_COPY_OUT:
+ case PGRES_COPY_BOTH:
/* Fine, do nothing */
OK = true;
break;
*************** ProcessResult(PGresult **results)
*** 751,756 ****
--- 752,758 ----
case PGRES_COPY_OUT:
case PGRES_COPY_IN:
+ case PGRES_COPY_BOTH:
is_copy = true;
break;
*************** ProcessResult(PGresult **results)
*** 777,784 ****
SetCancelConn();
if (result_status == PGRES_COPY_OUT)
{
! if (!copystream)
copystream = pset.queryFout;
success = handleCopyOut(pset.db,
copystream,
©_result) && success;
--- 779,793 ----
SetCancelConn();
if (result_status == PGRES_COPY_OUT)
{
! /*
! * If we have the stream for exceptions, then this must be the
! * capture phase: use it.
! */
! if (pset.copyExcStream)
! copystream = pset.copyExcStream;
! else if (!copystream)
copystream = pset.queryFout;
+
success = handleCopyOut(pset.db,
copystream,
©_result) && success;
*************** ProcessResult(PGresult **results)
*** 794,800 ****
copy_result = NULL;
}
}
! else
{
if (!copystream)
copystream = pset.cur_cmd_source;
--- 803,809 ----
copy_result = NULL;
}
}
! else /* PGRES_COPY_IN or PGRES_COPY_BOTH */
{
if (!copystream)
copystream = pset.cur_cmd_source;
*************** PrintQueryResults(PGresult *results)
*** 913,918 ****
--- 922,928 ----
case PGRES_COPY_OUT:
case PGRES_COPY_IN:
+ case PGRES_COPY_BOTH:
/* nothing to do here */
success = true;
break;
diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c
new file mode 100644
index 010a593..cc36071
*** a/src/bin/psql/copy.c
--- b/src/bin/psql/copy.c
*************** struct copy_options
*** 58,63 ****
--- 58,66 ----
bool program; /* is 'file' a program to popen? */
bool psql_inout; /* true = use psql stdin/stdout */
bool from; /* true = FROM, false = TO */
+ bool exceptions; /* has EXCEPTIONS TO */
+ char *exc_file; /* NULL = stdin/stdout */
+ bool exc_psql_inout; /* true = use psql stdout for exceptions */
};
*************** free_copy_options(struct copy_options *
*** 69,74 ****
--- 72,78 ----
free(ptr->before_tofrom);
free(ptr->after_tofrom);
free(ptr->file);
+ free(ptr->exc_file);
free(ptr);
}
*************** parse_slash_copy(const char *args)
*** 240,250 ****
expand_tilde(&result->file);
}
/* Collect the rest of the line (COPY options) */
token = strtokx(NULL, "", NULL, NULL,
0, false, false, pset.encoding);
if (token)
! result->after_tofrom = pg_strdup(token);
return result;
--- 244,302 ----
expand_tilde(&result->file);
}
+ result->after_tofrom = pg_strdup(""); /* initialize for appending */
+
+ /* check for COPY FROM ... EXCEPTIONS TO */
+ if (result->from)
+ {
+ token = strtokx(NULL, whitespace, NULL, NULL,
+ 0, false, false, pset.encoding);
+ if (token)
+ {
+ if (pg_strcasecmp(token, "exceptions") == 0)
+ {
+ result->exceptions = true;
+
+ token = strtokx(NULL, whitespace, NULL, NULL,
+ 0, false, false, pset.encoding);
+ if (!token || pg_strcasecmp(token, "to") != 0)
+ goto error;
+
+ token = strtokx(NULL, whitespace, ";", "'",
+ 0, false, false, pset.encoding);
+ if (!token)
+ goto error;
+
+ if (pg_strcasecmp(token, "stdin") == 0 ||
+ pg_strcasecmp(token, "stdout") == 0)
+ {
+ result->exc_file = NULL;
+ }
+ else if (pg_strcasecmp(token, "pstdin") == 0 ||
+ pg_strcasecmp(token, "pstdout") == 0)
+ {
+ result->exc_psql_inout = true;
+ result->exc_file = NULL;
+ }
+ else
+ {
+ strip_quotes(token, '\'', 0, pset.encoding);
+ result->exc_file = pg_strdup(token);
+ expand_tilde(&result->exc_file);
+ }
+ }
+ else
+ {
+ xstrcat(&result->after_tofrom, token);
+ }
+ }
+ }
+
/* Collect the rest of the line (COPY options) */
token = strtokx(NULL, "", NULL, NULL,
0, false, false, pset.encoding);
if (token)
! xstrcat(&result->after_tofrom, token);
return result;
*************** do_copy(const char *args)
*** 269,274 ****
--- 321,327 ----
{
PQExpBufferData query;
FILE *copystream;
+ FILE *excstream;
struct copy_options *options;
bool success;
*************** do_copy(const char *args)
*** 278,287 ****
if (!options)
return false;
! /* prepare to read or write the target file */
if (options->file && !options->program)
canonicalize_path(options->file);
if (options->from)
{
if (options->file)
--- 331,346 ----
if (!options)
return false;
! /* prepare to read or write the target file(s) */
if (options->file && !options->program)
canonicalize_path(options->file);
+ if (options->exc_file)
+ canonicalize_path(options->exc_file);
+
+ copystream = NULL;
+ excstream = NULL;
+
if (options->from)
{
if (options->file)
*************** do_copy(const char *args)
*** 294,305 ****
--- 353,394 ----
copystream = popen(options->file, PG_BINARY_R);
}
else
+ {
+ if (options->exc_file)
+ {
+ struct stat stbuf_exc;
+ struct stat stbuf_from;
+
+ /* check if both FROM and EXCEPTIONS TO are the same file */
+ if (stat(options->exc_file, &stbuf_exc) == 0 &&
+ stat(options->file, &stbuf_from) == 0 &&
+ stbuf_exc.st_dev == stbuf_from.st_dev &&
+ stbuf_exc.st_ino == stbuf_from.st_ino)
+ {
+ psql_error("COPY FROM and EXCEPTIONS TO cannot point to the same file\n");
+ free_copy_options(options);
+ return false;
+ }
+ }
copystream = fopen(options->file, PG_BINARY_R);
+ }
}
else if (!options->psql_inout)
copystream = pset.cur_cmd_source;
else
copystream = stdin;
+
+ if (options->exceptions)
+ {
+ if (options->exc_file)
+ {
+ excstream = fopen(options->exc_file, PG_BINARY_W);
+ }
+ else if (!options->exc_psql_inout)
+ excstream = pset.queryFout;
+ else
+ excstream = stdout;
+ }
}
else
{
*************** do_copy(const char *args)
*** 332,337 ****
--- 421,438 ----
else
psql_error("%s: %s\n",
options->file, strerror(errno));
+ if (options->exc_file && excstream)
+ fclose(excstream);
+ free_copy_options(options);
+ return false;
+ }
+
+ if (options->exceptions && !excstream)
+ {
+ psql_error("%s: %s\n",
+ options->exc_file, strerror(errno));
+ if (options->file)
+ fclose(copystream);
free_copy_options(options);
return false;
}
*************** do_copy(const char *args)
*** 353,358 ****
--- 454,461 ----
if (result < 0 || S_ISDIR(st.st_mode))
{
fclose(copystream);
+ if (options->exc_file && excstream)
+ fclose(excstream);
free_copy_options(options);
return false;
}
*************** do_copy(const char *args)
*** 366,378 ****
--- 469,485 ----
appendPQExpBufferStr(&query, " FROM STDIN ");
else
appendPQExpBufferStr(&query, " TO STDOUT ");
+ if (options->exceptions)
+ appendPQExpBufferStr(&query, " EXCEPTIONS TO STDOUT ");
if (options->after_tofrom)
appendPQExpBufferStr(&query, options->after_tofrom);
/* run it like a user command, but with copystream as data source/sink */
pset.copyStream = copystream;
+ pset.copyExcStream = excstream;
success = SendQuery(query.data);
pset.copyStream = NULL;
+ pset.copyExcStream = NULL;
termPQExpBuffer(&query);
if (options->file != NULL)
*************** do_copy(const char *args)
*** 410,415 ****
--- 517,530 ----
}
}
}
+ if (options->exc_file != NULL)
+ {
+ if (fclose(excstream) != 0)
+ {
+ psql_error("%s: %s\n", options->exc_file, strerror(errno));
+ success = false;
+ }
+ }
free_copy_options(options);
return success;
}
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
new file mode 100644
index ef24a4e..36c9300
*** a/src/bin/psql/settings.h
--- b/src/bin/psql/settings.h
*************** typedef struct _psqlSettings
*** 72,77 ****
--- 72,78 ----
bool queryFoutPipe; /* queryFout is from a popen() */
FILE *copyStream; /* Stream to read/write for \copy command */
+ FILE *copyExcStream; /* Stream to read exceptions for \copy command */
printQueryOpt popt;
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
new file mode 100644
index 11a159a..f1f65df
*** a/src/bin/psql/startup.c
--- b/src/bin/psql/startup.c
*************** main(int argc, char *argv[])
*** 122,127 ****
--- 122,128 ----
pset.queryFout = stdout;
pset.queryFoutPipe = false;
pset.copyStream = NULL;
+ pset.copyExcStream = NULL;
pset.cur_cmd_source = stdin;
pset.cur_cmd_interactive = false;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
new file mode 100644
index 82c926d..361cd80
*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
*************** psql_completion(const char *text, int st
*** 2169,2175 ****
completion_charp = "";
matches = completion_matches(text, complete_from_files);
}
-
/* Handle COPY|BINARY <sth> FROM|TO filename */
else if ((pg_strcasecmp(prev4_wd, "COPY") == 0 ||
pg_strcasecmp(prev4_wd, "\\copy") == 0 ||
--- 2169,2174 ----
*************** psql_completion(const char *text, int st
*** 2178,2187 ****
pg_strcasecmp(prev2_wd, "TO") == 0))
{
static const char *const list_COPY[] =
! {"BINARY", "OIDS", "DELIMITER", "NULL", "CSV", "ENCODING", NULL};
!
COMPLETE_WITH_LIST(list_COPY);
}
/* Handle COPY|BINARY <sth> FROM|TO filename CSV */
else if (pg_strcasecmp(prev_wd, "CSV") == 0 &&
--- 2177,2193 ----
pg_strcasecmp(prev2_wd, "TO") == 0))
{
static const char *const list_COPY[] =
! {"BINARY", "OIDS", "DELIMITER", "NULL", "CSV", "ENCODING", "EXCEPTIONS TO", NULL};
COMPLETE_WITH_LIST(list_COPY);
}
+ /* If we have [COPY...] FROM <sth> EXCEPTIONS TO, complete with filename */
+ else if (pg_strcasecmp(prev4_wd, "FROM") == 0 &&
+ pg_strcasecmp(prev2_wd, "EXCEPTIONS") == 0 &&
+ pg_strcasecmp(prev_wd, "TO") == 0)
+ {
+ completion_charp = "";
+ matches = completion_matches(text, complete_from_files);
+ }
/* Handle COPY|BINARY <sth> FROM|TO filename CSV */
else if (pg_strcasecmp(prev_wd, "CSV") == 0 &&
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
new file mode 100644
index ba0f1b3..7137dfc
*** a/src/include/commands/copy.h
--- b/src/include/commands/copy.h
*************** extern Oid DoCopy(const CopyStmt *stmt,
*** 26,32 ****
extern void ProcessCopyOptions(CopyState cstate, bool is_from, List *options);
extern CopyState BeginCopyFrom(Relation rel, const char *filename,
! bool is_program, List *attnamelist, List *options);
extern void EndCopyFrom(CopyState cstate);
extern bool NextCopyFrom(CopyState cstate, ExprContext *econtext,
Datum *values, bool *nulls, Oid *tupleOid);
--- 26,33 ----
extern void ProcessCopyOptions(CopyState cstate, bool is_from, List *options);
extern CopyState BeginCopyFrom(Relation rel, const char *filename,
! bool is_program, const char *exc_filename,
! List *attnamelist, List *options);
extern void EndCopyFrom(CopyState cstate);
extern bool NextCopyFrom(CopyState cstate, ExprContext *econtext,
Datum *values, bool *nulls, Oid *tupleOid);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
new file mode 100644
index 9141c30..93f50cb
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
*************** typedef struct CopyStmt
*** 1513,1518 ****
--- 1513,1519 ----
bool is_from; /* TO or FROM */
bool is_program; /* is 'filename' a program to popen? */
char *filename; /* filename, or NULL for STDIN/STDOUT */
+ char *exc_filename; /* filename for exceptions or NULL, empty string for STDOUT */
List *options; /* List of DefElem nodes */
} CopyStmt;
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
new file mode 100644
index e14dc9a..c44f02b
*** a/src/include/parser/kwlist.h
--- b/src/include/parser/kwlist.h
*************** PG_KEYWORD("enum", ENUM_P, UNRESERVED_KE
*** 143,148 ****
--- 143,149 ----
PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD)
PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD)
PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD)
+ PG_KEYWORD("exceptions", EXCEPTIONS, UNRESERVED_KEYWORD)
PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD)
PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD)
PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD)
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
new file mode 100644
index b3b36cf..0a415e6
*** a/src/interfaces/ecpg/preproc/ecpg.addons
--- b/src/interfaces/ecpg/preproc/ecpg.addons
*************** ECPG: where_or_current_clauseWHERECURREN
*** 192,198 ****
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
$$ = cat_str(2,mm_strdup("where current of"), cursor_marker);
}
! ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromopt_programcopy_file_namecopy_delimiteropt_withcopy_options addon
if (strcmp($6, "from") == 0 &&
(strcmp($7, "stdin") == 0 || strcmp($7, "stdout") == 0))
mmerror(PARSE_ERROR, ET_WARNING, "COPY FROM STDIN is not implemented");
--- 192,198 ----
char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
$$ = cat_str(2,mm_strdup("where current of"), cursor_marker);
}
! ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromopt_programcopy_file_nameopt_copy_exceptionscopy_delimiteropt_withcopy_options addon
if (strcmp($6, "from") == 0 &&
(strcmp($7, "stdin") == 0 || strcmp($7, "stdout") == 0))
mmerror(PARSE_ERROR, ET_WARNING, "COPY FROM STDIN is not implemented");
--
2.1.0
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
@ 2014-12-26 10:41 ` Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Pavel Stehule @ 2014-12-26 10:41 UTC (permalink / raw)
To: Alex Shulgin <[email protected]>; +Cc: pgsql-hackers
2014-12-25 22:23 GMT+01:00 Alex Shulgin <[email protected]>:
> Trent Shipley <[email protected]> writes:
>
> > On Friday 2007-12-14 16:22, Tom Lane wrote:
> >> Neil Conway <[email protected]> writes:
> >> > By modifying COPY: COPY IGNORE ERRORS or some such would instruct COPY
> >> > to drop (and log) rows that contain malformed data. That is, rows with
> >> > too many or too few columns, rows that result in constraint
> violations,
> >> > and rows containing columns where the data type's input function
> raises
> >> > an error. The last case is the only thing that would be a bit tricky
> to
> >> > implement, I think: you could use PG_TRY() around the
> InputFunctionCall,
> >> > but I guess you'd need a subtransaction to ensure that you reset your
> >> > state correctly after catching an error.
> >>
> >> Yeah. It's the subtransaction per row that's daunting --- not only the
> >> cycles spent for that, but the ensuing limitation to 4G rows imported
> >> per COPY.
> >
> > You could extend the COPY FROM syntax with a COMMIT EVERY n clause. This
> > would help with the 4G subtransaction limit. The cost to the ETL
> process is
> > that a simple rollback would not be guaranteed send the process back to
> it's
> > initial state. There are easy ways to deal with the rollback issue
> though.
> >
> > A {NO} RETRY {USING algorithm} clause might be useful. If the NO RETRY
> > option is selected then the COPY FROM can run without subtransactions
> and in
> > excess of the 4G per transaction limit. NO RETRY should be the default
> since
> > it preserves the legacy behavior of COPY FROM.
> >
> > You could have an EXCEPTIONS TO {filename|STDERR} clause. I would not
> give the
> > option of sending exceptions to a table since they are presumably
> malformed,
> > otherwise they would not be exceptions. (Users should re-process
> exception
> > files if they want an if good then table a else exception to table b ...)
> >
> > EXCEPTIONS TO and NO RETRY would be mutually exclusive.
> >
> >
> >> If we could somehow only do a subtransaction per failure, things would
> >> be much better, but I don't see how.
>
> Hello,
>
> Attached is a proof of concept patch for this TODO item. There is no
> docs yet, I just wanted to know if approach is sane.
>
> The added syntax is like the following:
>
> COPY [table] FROM [file/program/stdin] EXCEPTIONS TO [file or stdout]
>
> The way it's done it is abusing Copy Both mode and from my limited
> testing, that seems to just work. The error trapping itself is done
> using PG_TRY/PG_CATCH and can only catch formatting or before-insert
> trigger errors, no attempt is made to recover from a failed unique
> constraint, etc.
>
> Example in action:
>
> postgres=# \d test_copy2
> Table "public.test_copy2"
> Column | Type | Modifiers
> --------+---------+-----------
> id | integer |
> val | integer |
>
> postgres=# copy test_copy2 from program 'seq 3' exceptions to stdout;
> 1
> NOTICE: missing data for column "val"
> CONTEXT: COPY test_copy2, line 1: "1"
> 2
> NOTICE: missing data for column "val"
> CONTEXT: COPY test_copy2, line 2: "2"
> 3
> NOTICE: missing data for column "val"
> CONTEXT: COPY test_copy2, line 3: "3"
> NOTICE: total exceptions ignored: 3
>
> postgres=# \d test_copy1
> Table "public.test_copy1"
> Column | Type | Modifiers
> --------+---------+-----------
> id | integer | not null
>
> postgres=# set client_min_messages to warning;
> SET
> postgres=# copy test_copy1 from program 'ls /proc' exceptions to stdout;
> ...
> vmstat
> zoneinfo
> postgres=#
>
> Limited performance testing shows no significant difference between
> error-catching and plain code path. For example, timing
>
> copy test_copy1 from program 'seq 1000000' [exceptions to stdout]
>
> shows similar numbers with or without the added "exceptions to" clause.
>
> Now that I'm sending this I wonder if the original comment about the
> need for subtransaction around every loaded line still holds. Any
> example of what would be not properly rolled back by just PG_TRY?
>
this method is unsafe .. exception handlers doesn't free memory usually -
there is risk of memory leaks, source leaks
you can enforce same performance with block subtransactions - when you use
subtransaction for 1000 rows, then impact of subtransactions is minimal
when block fails, then you can use row level subtransaction - it works well
when you expect almost correct data.
Regards
Pavel
>
> Happy hacking!
> --
> Alex
>
>
>
> --
> Sent via pgsql-hackers mailing list ([email protected])
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
>
>
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
@ 2014-12-26 10:49 ` Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Pavel Stehule @ 2014-12-26 10:49 UTC (permalink / raw)
To: Alex Shulgin <[email protected]>; +Cc: pgsql-hackers
2014-12-26 11:41 GMT+01:00 Pavel Stehule <[email protected]>:
>
>
> 2014-12-25 22:23 GMT+01:00 Alex Shulgin <[email protected]>:
>
>> Trent Shipley <[email protected]> writes:
>>
>> > On Friday 2007-12-14 16:22, Tom Lane wrote:
>> >> Neil Conway <[email protected]> writes:
>> >> > By modifying COPY: COPY IGNORE ERRORS or some such would instruct
>> COPY
>> >> > to drop (and log) rows that contain malformed data. That is, rows
>> with
>> >> > too many or too few columns, rows that result in constraint
>> violations,
>> >> > and rows containing columns where the data type's input function
>> raises
>> >> > an error. The last case is the only thing that would be a bit tricky
>> to
>> >> > implement, I think: you could use PG_TRY() around the
>> InputFunctionCall,
>> >> > but I guess you'd need a subtransaction to ensure that you reset your
>> >> > state correctly after catching an error.
>> >>
>> >> Yeah. It's the subtransaction per row that's daunting --- not only the
>> >> cycles spent for that, but the ensuing limitation to 4G rows imported
>> >> per COPY.
>> >
>> > You could extend the COPY FROM syntax with a COMMIT EVERY n clause.
>> This
>> > would help with the 4G subtransaction limit. The cost to the ETL
>> process is
>> > that a simple rollback would not be guaranteed send the process back to
>> it's
>> > initial state. There are easy ways to deal with the rollback issue
>> though.
>> >
>> > A {NO} RETRY {USING algorithm} clause might be useful. If the NO RETRY
>> > option is selected then the COPY FROM can run without subtransactions
>> and in
>> > excess of the 4G per transaction limit. NO RETRY should be the default
>> since
>> > it preserves the legacy behavior of COPY FROM.
>> >
>> > You could have an EXCEPTIONS TO {filename|STDERR} clause. I would not
>> give the
>> > option of sending exceptions to a table since they are presumably
>> malformed,
>> > otherwise they would not be exceptions. (Users should re-process
>> exception
>> > files if they want an if good then table a else exception to table b
>> ...)
>> >
>> > EXCEPTIONS TO and NO RETRY would be mutually exclusive.
>> >
>> >
>> >> If we could somehow only do a subtransaction per failure, things would
>> >> be much better, but I don't see how.
>>
>> Hello,
>>
>> Attached is a proof of concept patch for this TODO item. There is no
>> docs yet, I just wanted to know if approach is sane.
>>
>> The added syntax is like the following:
>>
>> COPY [table] FROM [file/program/stdin] EXCEPTIONS TO [file or stdout]
>>
>> The way it's done it is abusing Copy Both mode and from my limited
>> testing, that seems to just work. The error trapping itself is done
>> using PG_TRY/PG_CATCH and can only catch formatting or before-insert
>> trigger errors, no attempt is made to recover from a failed unique
>> constraint, etc.
>>
>> Example in action:
>>
>> postgres=# \d test_copy2
>> Table "public.test_copy2"
>> Column | Type | Modifiers
>> --------+---------+-----------
>> id | integer |
>> val | integer |
>>
>> postgres=# copy test_copy2 from program 'seq 3' exceptions to stdout;
>> 1
>> NOTICE: missing data for column "val"
>> CONTEXT: COPY test_copy2, line 1: "1"
>> 2
>> NOTICE: missing data for column "val"
>> CONTEXT: COPY test_copy2, line 2: "2"
>> 3
>> NOTICE: missing data for column "val"
>> CONTEXT: COPY test_copy2, line 3: "3"
>> NOTICE: total exceptions ignored: 3
>>
>> postgres=# \d test_copy1
>> Table "public.test_copy1"
>> Column | Type | Modifiers
>> --------+---------+-----------
>> id | integer | not null
>>
>> postgres=# set client_min_messages to warning;
>> SET
>> postgres=# copy test_copy1 from program 'ls /proc' exceptions to stdout;
>> ...
>> vmstat
>> zoneinfo
>> postgres=#
>>
>> Limited performance testing shows no significant difference between
>> error-catching and plain code path. For example, timing
>>
>> copy test_copy1 from program 'seq 1000000' [exceptions to stdout]
>>
>> shows similar numbers with or without the added "exceptions to" clause.
>>
>> Now that I'm sending this I wonder if the original comment about the
>> need for subtransaction around every loaded line still holds. Any
>> example of what would be not properly rolled back by just PG_TRY?
>>
>
> this method is unsafe .. exception handlers doesn't free memory usually -
> there is risk of memory leaks, source leaks
>
> you can enforce same performance with block subtransactions - when you use
> subtransaction for 1000 rows, then impact of subtransactions is minimal
>
> when block fails, then you can use row level subtransaction - it works
> well when you expect almost correct data.
>
Two years ago I wrote a extension that did it - but I have not time to
finish it and push to upstream.
Regards
Pavel
>
> Regards
>
> Pavel
>
>
>>
>> Happy hacking!
>> --
>> Alex
>>
>>
>>
>> --
>> Sent via pgsql-hackers mailing list ([email protected])
>> To make changes to your subscription:
>> http://www.postgresql.org/mailpref/pgsql-hackers
>>
>>
>
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Attachments:
[application/x-gzip] ftcopy-04.tgz (12.6K, ../../CAFj8pRD9Pi9besMvv0Yo0A4wqQ-D=cBXGRQhz_oS+BNgv_41_Q@mail.gmail.com/3-ftcopy-04.tgz)
download
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
@ 2021-12-18 08:55 ` Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2021-12-18 08:55 UTC (permalink / raw)
To: ; +Cc: pgsql-hackers
Hello.
Wrote a patch implementing COPY with ignoring errors in rows using block
subtransactions.
Syntax: COPY [table] FROM [file/stdin] WITH IGNORE_ERROS;
Examples:
CREATE TABLE check_ign_err (n int, m int, k int);
COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
1 1 1
2 2 2 2
3 3 3
\.
WARNING: COPY check_ign_err, line 2: "2 2 2 2"
SELECT * FROM check_ign_err;
n | m | k
---+---+---
1 | 1 | 1
3 | 3 | 3
(2 rows)
##################################################
TRUNCATE check_ign_err;
COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
1 1 1
2 2
3 3 3
\.
WARNING: COPY check_ign_err, line 2: "2 2"
SELECT * FROM check_ign_err;
n | m | k
---+---+---
1 | 1 | 1
3 | 3 | 3
(2 rows)
##################################################
TRUNCATE check_ign_err;
COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
1 1 1
2 a 2
3 3 3
\.
WARNING: COPY check_ign_err, line 2, column m: "a"
SELECT * FROM check_ign_err;
n | m | k
---+---+---
1 | 1 | 1
3 | 3 | 3
(2 rows)
Regards, Damir
пт, 10 дек. 2021 г. в 21:48, Pavel Stehule <[email protected]>:
>
>
> 2014-12-26 11:41 GMT+01:00 Pavel Stehule <[email protected]>:
>
>>
>>
>> 2014-12-25 22:23 GMT+01:00 Alex Shulgin <[email protected]>:
>>
>>> Trent Shipley <[email protected]> writes:
>>>
>>> > On Friday 2007-12-14 16:22, Tom Lane wrote:
>>> >> Neil Conway <[email protected]> writes:
>>> >> > By modifying COPY: COPY IGNORE ERRORS or some such would instruct
>>> COPY
>>> >> > to drop (and log) rows that contain malformed data. That is, rows
>>> with
>>> >> > too many or too few columns, rows that result in constraint
>>> violations,
>>> >> > and rows containing columns where the data type's input function
>>> raises
>>> >> > an error. The last case is the only thing that would be a bit
>>> tricky to
>>> >> > implement, I think: you could use PG_TRY() around the
>>> InputFunctionCall,
>>> >> > but I guess you'd need a subtransaction to ensure that you reset
>>> your
>>> >> > state correctly after catching an error.
>>> >>
>>> >> Yeah. It's the subtransaction per row that's daunting --- not only
>>> the
>>> >> cycles spent for that, but the ensuing limitation to 4G rows imported
>>> >> per COPY.
>>> >
>>> > You could extend the COPY FROM syntax with a COMMIT EVERY n clause.
>>> This
>>> > would help with the 4G subtransaction limit. The cost to the ETL
>>> process is
>>> > that a simple rollback would not be guaranteed send the process back
>>> to it's
>>> > initial state. There are easy ways to deal with the rollback issue
>>> though.
>>> >
>>> > A {NO} RETRY {USING algorithm} clause might be useful. If the NO
>>> RETRY
>>> > option is selected then the COPY FROM can run without subtransactions
>>> and in
>>> > excess of the 4G per transaction limit. NO RETRY should be the
>>> default since
>>> > it preserves the legacy behavior of COPY FROM.
>>> >
>>> > You could have an EXCEPTIONS TO {filename|STDERR} clause. I would not
>>> give the
>>> > option of sending exceptions to a table since they are presumably
>>> malformed,
>>> > otherwise they would not be exceptions. (Users should re-process
>>> exception
>>> > files if they want an if good then table a else exception to table b
>>> ...)
>>> >
>>> > EXCEPTIONS TO and NO RETRY would be mutually exclusive.
>>> >
>>> >
>>> >> If we could somehow only do a subtransaction per failure, things would
>>> >> be much better, but I don't see how.
>>>
>>> Hello,
>>>
>>> Attached is a proof of concept patch for this TODO item. There is no
>>> docs yet, I just wanted to know if approach is sane.
>>>
>>> The added syntax is like the following:
>>>
>>> COPY [table] FROM [file/program/stdin] EXCEPTIONS TO [file or stdout]
>>>
>>> The way it's done it is abusing Copy Both mode and from my limited
>>> testing, that seems to just work. The error trapping itself is done
>>> using PG_TRY/PG_CATCH and can only catch formatting or before-insert
>>> trigger errors, no attempt is made to recover from a failed unique
>>> constraint, etc.
>>>
>>> Example in action:
>>>
>>> postgres=# \d test_copy2
>>> Table "public.test_copy2"
>>> Column | Type | Modifiers
>>> --------+---------+-----------
>>> id | integer |
>>> val | integer |
>>>
>>> postgres=# copy test_copy2 from program 'seq 3' exceptions to stdout;
>>> 1
>>> NOTICE: missing data for column "val"
>>> CONTEXT: COPY test_copy2, line 1: "1"
>>> 2
>>> NOTICE: missing data for column "val"
>>> CONTEXT: COPY test_copy2, line 2: "2"
>>> 3
>>> NOTICE: missing data for column "val"
>>> CONTEXT: COPY test_copy2, line 3: "3"
>>> NOTICE: total exceptions ignored: 3
>>>
>>> postgres=# \d test_copy1
>>> Table "public.test_copy1"
>>> Column | Type | Modifiers
>>> --------+---------+-----------
>>> id | integer | not null
>>>
>>> postgres=# set client_min_messages to warning;
>>> SET
>>> postgres=# copy test_copy1 from program 'ls /proc' exceptions to stdout;
>>> ...
>>> vmstat
>>> zoneinfo
>>> postgres=#
>>>
>>> Limited performance testing shows no significant difference between
>>> error-catching and plain code path. For example, timing
>>>
>>> copy test_copy1 from program 'seq 1000000' [exceptions to stdout]
>>>
>>> shows similar numbers with or without the added "exceptions to" clause.
>>>
>>> Now that I'm sending this I wonder if the original comment about the
>>> need for subtransaction around every loaded line still holds. Any
>>> example of what would be not properly rolled back by just PG_TRY?
>>>
>>
>> this method is unsafe .. exception handlers doesn't free memory usually -
>> there is risk of memory leaks, source leaks
>>
>> you can enforce same performance with block subtransactions - when you
>> use subtransaction for 1000 rows, then impact of subtransactions is minimal
>>
>> when block fails, then you can use row level subtransaction - it works
>> well when you expect almost correct data.
>>
>
> Two years ago I wrote a extension that did it - but I have not time to
> finish it and push to upstream.
>
> Regards
>
> Pavel
>
>
>>
>> Regards
>>
>> Pavel
>>
>>
>>>
>>> Happy hacking!
>>> --
>>> Alex
>>>
>>>
>>>
>>> --
>>> Sent via pgsql-hackers mailing list ([email protected])
>>> To make changes to your subscription:
>>> http://www.postgresql.org/mailpref/pgsql-hackers
>>>
>>>
>>
>
> --
> Sent via pgsql-hackers mailing list ([email protected])
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
>
Attachments:
[text/x-patch] 0001-COPY-IGNORE_ERRORS-option.patch (35.3K, ../../CALH1LgsKDk4XthrM4m8tAqfoPyNgDCSFV3Go1nevXze-8dwKrA@mail.gmail.com/3-0001-COPY-IGNORE_ERRORS-option.patch)
download | inline diff:
From b2dbe11f103655bf845aabc3d7af3697d1441b43 Mon Sep 17 00:00:00 2001
From: Damir Belyalov <[email protected]>
Date: Fri, 15 Oct 2021 11:55:18 +0300
Subject: [PATCH] COPY IGNORE_ERRORS option
---
doc/src/sgml/ref/copy.sgml | 13 +
src/backend/commands/copy.c | 8 +
src/backend/commands/copyfrom.c | 72 ++++-
src/backend/commands/copyfromparse.c | 13 +-
src/backend/parser/gram.y | 8 +-
src/backend/utils/.gitignore | 1 -
src/backend/utils/errcodes.h | 354 +++++++++++++++++++++++
src/bin/psql/tab-complete.c | 3 +-
src/include/commands/copy.h | 1 +
src/include/commands/copyfrom_internal.h | 1 +
src/include/parser/kwlist.h | 1 +
src/test/regress/expected/copy2.out | 32 ++
src/test/regress/sql/copy2.sql | 26 ++
13 files changed, 525 insertions(+), 8 deletions(-)
create mode 100644 src/backend/utils/errcodes.h
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 4624c8f4c9..5ca8ff876d 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> ]
@@ -233,6 +234,18 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drop rows that contain malformed data while copying. That is rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows that result in constraint violations, rows containing columns where
+ the data type's input function raises an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 53f4853141..9ddc8c3d96 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -337,6 +337,7 @@ ProcessCopyOptions(ParseState *pstate,
{
bool format_specified = false;
bool freeze_specified = false;
+ bool ignore_errors_specified = false;
bool header_specified = false;
ListCell *option;
@@ -377,6 +378,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index f366a818a1..d416222faf 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -852,9 +852,75 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
- break;
+ /*
+ * If option IGNORE_ERRORS is enabled, COPY skip rows with errors.
+ * NextCopyFrom() directly store the values/nulls array in the slot.
+ */
+ if (cstate->opts.ignore_errors)
+ {
+ bool break_for = false;
+ bool skip_tuple_ignore_errors = false;
+ MemoryContext ccxt = CurrentMemoryContext;
+ ResourceOwner oldowner = CurrentResourceOwner;
+
+ BeginInternalSubTransaction(NULL);
+ MemoryContextSwitchTo(ccxt);
+
+ PG_TRY();
+ {
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ {
+ // can't do break in PG_TRY
+ break_for = true;
+ }
+
+ ReleaseCurrentSubTransaction();
+ MemoryContextSwitchTo(ccxt);
+ CurrentResourceOwner = oldowner;
+ }
+ PG_CATCH();
+ {
+ MemoryContext ecxt = MemoryContextSwitchTo(ccxt);
+ ErrorData *errdata = CopyErrorData();
+
+ switch (errdata->sqlerrcode)
+ {
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ skip_tuple_ignore_errors = true;
+ elog(WARNING, errdata->context);
+
+ RollbackAndReleaseCurrentSubTransaction();
+ MemoryContextSwitchTo(ccxt);
+ CurrentResourceOwner = oldowner;
+
+ ExecClearTuple(myslot);
+ MemSet(myslot->tts_values, 0, cstate->attr_count * sizeof(Datum));
+ MemSet(myslot->tts_isnull, true, cstate->attr_count * sizeof(bool));
+
+ break;
+ default:
+ MemoryContextSwitchTo(ecxt);
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+ }
+ PG_END_TRY();
+
+ if (break_for)
+ break;
+
+ if (skip_tuple_ignore_errors)
+ continue;
+ }
+ else
+ {
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
+ }
ExecStoreVirtualTuple(myslot);
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index aac10165ec..702b70861d 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -817,6 +817,7 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
tupDesc = RelationGetDescr(cstate->rel);
num_phys_attrs = tupDesc->natts;
attr_count = list_length(cstate->attnumlist);
+ cstate->attr_count = attr_count;
/* Initialize all values for row to NULL */
MemSet(values, 0, num_phys_attrs * sizeof(Datum));
@@ -893,6 +894,7 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
string,
typioparams[m],
att->atttypmod);
+
if (string != NULL)
nulls[m] = false;
cstate->cur_attname = NULL;
@@ -1446,10 +1448,17 @@ CopyReadAttributesText(CopyFromState cstate)
if (cstate->max_fields <= 0)
{
if (cstate->line_buf.len != 0)
- ereport(ERROR,
- (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
+ {
+ if (cstate->opts.ignore_errors)
+ ereport(ERROR,
+ (errcode(ERRCODE_FOR_IGNORE_ERRORS),
errmsg("extra data after last expected column")));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
+ errmsg("extra data after last expected column")));
return 0;
+ }
}
resetStringInfo(&cstate->attribute_buf);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 86ce33bd97..5f6863e5e1 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -674,7 +674,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3160,6 +3160,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *)makeInteger(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeInteger(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *)makeString($3), @1);
@@ -15659,6 +15663,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -16209,6 +16214,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/backend/utils/.gitignore b/src/backend/utils/.gitignore
index 0685556959..3c679d07ff 100644
--- a/src/backend/utils/.gitignore
+++ b/src/backend/utils/.gitignore
@@ -3,4 +3,3 @@
/fmgrprotos.h
/fmgr-stamp
/probes.h
-/errcodes.h
diff --git a/src/backend/utils/errcodes.h b/src/backend/utils/errcodes.h
new file mode 100644
index 0000000000..b187599bdd
--- /dev/null
+++ b/src/backend/utils/errcodes.h
@@ -0,0 +1,354 @@
+/* autogenerated from src/backend/utils/errcodes.txt, do not edit */
+/* there is deliberately not an #ifndef ERRCODES_H here */
+
+/* Class 00 - Successful Completion */
+#define ERRCODE_SUCCESSFUL_COMPLETION MAKE_SQLSTATE('0','0','0','0','0')
+
+/* Class 01 - Warning */
+#define ERRCODE_WARNING MAKE_SQLSTATE('0','1','0','0','0')
+#define ERRCODE_WARNING_DYNAMIC_RESULT_SETS_RETURNED MAKE_SQLSTATE('0','1','0','0','C')
+#define ERRCODE_WARNING_IMPLICIT_ZERO_BIT_PADDING MAKE_SQLSTATE('0','1','0','0','8')
+#define ERRCODE_WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION MAKE_SQLSTATE('0','1','0','0','3')
+#define ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED MAKE_SQLSTATE('0','1','0','0','7')
+#define ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED MAKE_SQLSTATE('0','1','0','0','6')
+#define ERRCODE_WARNING_STRING_DATA_RIGHT_TRUNCATION MAKE_SQLSTATE('0','1','0','0','4')
+#define ERRCODE_WARNING_DEPRECATED_FEATURE MAKE_SQLSTATE('0','1','P','0','1')
+
+/* Class 02 - No Data (this is also a warning class per the SQL standard) */
+#define ERRCODE_NO_DATA MAKE_SQLSTATE('0','2','0','0','0')
+#define ERRCODE_NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED MAKE_SQLSTATE('0','2','0','0','1')
+
+/* Class 03 - SQL Statement Not Yet Complete */
+#define ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE MAKE_SQLSTATE('0','3','0','0','0')
+
+/* Class 08 - Connection Exception */
+#define ERRCODE_CONNECTION_EXCEPTION MAKE_SQLSTATE('0','8','0','0','0')
+#define ERRCODE_CONNECTION_DOES_NOT_EXIST MAKE_SQLSTATE('0','8','0','0','3')
+#define ERRCODE_CONNECTION_FAILURE MAKE_SQLSTATE('0','8','0','0','6')
+#define ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION MAKE_SQLSTATE('0','8','0','0','1')
+#define ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION MAKE_SQLSTATE('0','8','0','0','4')
+#define ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN MAKE_SQLSTATE('0','8','0','0','7')
+#define ERRCODE_PROTOCOL_VIOLATION MAKE_SQLSTATE('0','8','P','0','1')
+
+/* Class 09 - Triggered Action Exception */
+#define ERRCODE_TRIGGERED_ACTION_EXCEPTION MAKE_SQLSTATE('0','9','0','0','0')
+
+/* Class 0A - Feature Not Supported */
+#define ERRCODE_FEATURE_NOT_SUPPORTED MAKE_SQLSTATE('0','A','0','0','0')
+
+/* Class 0B - Invalid Transaction Initiation */
+#define ERRCODE_INVALID_TRANSACTION_INITIATION MAKE_SQLSTATE('0','B','0','0','0')
+
+/* Class 0F - Locator Exception */
+#define ERRCODE_LOCATOR_EXCEPTION MAKE_SQLSTATE('0','F','0','0','0')
+#define ERRCODE_L_E_INVALID_SPECIFICATION MAKE_SQLSTATE('0','F','0','0','1')
+
+/* Class 0L - Invalid Grantor */
+#define ERRCODE_INVALID_GRANTOR MAKE_SQLSTATE('0','L','0','0','0')
+#define ERRCODE_INVALID_GRANT_OPERATION MAKE_SQLSTATE('0','L','P','0','1')
+
+/* Class 0P - Invalid Role Specification */
+#define ERRCODE_INVALID_ROLE_SPECIFICATION MAKE_SQLSTATE('0','P','0','0','0')
+
+/* Class 0Z - Diagnostics Exception */
+#define ERRCODE_DIAGNOSTICS_EXCEPTION MAKE_SQLSTATE('0','Z','0','0','0')
+#define ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER MAKE_SQLSTATE('0','Z','0','0','2')
+
+/* Class 20 - Case Not Found */
+#define ERRCODE_CASE_NOT_FOUND MAKE_SQLSTATE('2','0','0','0','0')
+
+/* Class 21 - Cardinality Violation */
+#define ERRCODE_CARDINALITY_VIOLATION MAKE_SQLSTATE('2','1','0','0','0')
+
+/* Class 22 - Data Exception */
+#define ERRCODE_DATA_EXCEPTION MAKE_SQLSTATE('2','2','0','0','0')
+#define ERRCODE_ARRAY_ELEMENT_ERROR MAKE_SQLSTATE('2','2','0','2','E')
+#define ERRCODE_ARRAY_SUBSCRIPT_ERROR MAKE_SQLSTATE('2','2','0','2','E')
+#define ERRCODE_CHARACTER_NOT_IN_REPERTOIRE MAKE_SQLSTATE('2','2','0','2','1')
+#define ERRCODE_DATETIME_FIELD_OVERFLOW MAKE_SQLSTATE('2','2','0','0','8')
+#define ERRCODE_DATETIME_VALUE_OUT_OF_RANGE MAKE_SQLSTATE('2','2','0','0','8')
+#define ERRCODE_DIVISION_BY_ZERO MAKE_SQLSTATE('2','2','0','1','2')
+#define ERRCODE_ERROR_IN_ASSIGNMENT MAKE_SQLSTATE('2','2','0','0','5')
+#define ERRCODE_ESCAPE_CHARACTER_CONFLICT MAKE_SQLSTATE('2','2','0','0','B')
+#define ERRCODE_INDICATOR_OVERFLOW MAKE_SQLSTATE('2','2','0','2','2')
+#define ERRCODE_INTERVAL_FIELD_OVERFLOW MAKE_SQLSTATE('2','2','0','1','5')
+#define ERRCODE_INVALID_ARGUMENT_FOR_LOG MAKE_SQLSTATE('2','2','0','1','E')
+#define ERRCODE_INVALID_ARGUMENT_FOR_NTILE MAKE_SQLSTATE('2','2','0','1','4')
+#define ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE MAKE_SQLSTATE('2','2','0','1','6')
+#define ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION MAKE_SQLSTATE('2','2','0','1','F')
+#define ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION MAKE_SQLSTATE('2','2','0','1','G')
+#define ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST MAKE_SQLSTATE('2','2','0','1','8')
+#define ERRCODE_INVALID_DATETIME_FORMAT MAKE_SQLSTATE('2','2','0','0','7')
+#define ERRCODE_INVALID_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','0','1','9')
+#define ERRCODE_INVALID_ESCAPE_OCTET MAKE_SQLSTATE('2','2','0','0','D')
+#define ERRCODE_INVALID_ESCAPE_SEQUENCE MAKE_SQLSTATE('2','2','0','2','5')
+#define ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','P','0','6')
+#define ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE MAKE_SQLSTATE('2','2','0','1','0')
+#define ERRCODE_INVALID_PARAMETER_VALUE MAKE_SQLSTATE('2','2','0','2','3')
+#define ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE MAKE_SQLSTATE('2','2','0','1','3')
+#define ERRCODE_INVALID_REGULAR_EXPRESSION MAKE_SQLSTATE('2','2','0','1','B')
+#define ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE MAKE_SQLSTATE('2','2','0','1','W')
+#define ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE MAKE_SQLSTATE('2','2','0','1','X')
+#define ERRCODE_INVALID_TABLESAMPLE_ARGUMENT MAKE_SQLSTATE('2','2','0','2','H')
+#define ERRCODE_INVALID_TABLESAMPLE_REPEAT MAKE_SQLSTATE('2','2','0','2','G')
+#define ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE MAKE_SQLSTATE('2','2','0','0','9')
+#define ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','0','0','C')
+#define ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH MAKE_SQLSTATE('2','2','0','0','G')
+#define ERRCODE_NULL_VALUE_NOT_ALLOWED MAKE_SQLSTATE('2','2','0','0','4')
+#define ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER MAKE_SQLSTATE('2','2','0','0','2')
+#define ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE MAKE_SQLSTATE('2','2','0','0','3')
+#define ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED MAKE_SQLSTATE('2','2','0','0','H')
+#define ERRCODE_STRING_DATA_LENGTH_MISMATCH MAKE_SQLSTATE('2','2','0','2','6')
+#define ERRCODE_STRING_DATA_RIGHT_TRUNCATION MAKE_SQLSTATE('2','2','0','0','1')
+#define ERRCODE_SUBSTRING_ERROR MAKE_SQLSTATE('2','2','0','1','1')
+#define ERRCODE_TRIM_ERROR MAKE_SQLSTATE('2','2','0','2','7')
+#define ERRCODE_UNTERMINATED_C_STRING MAKE_SQLSTATE('2','2','0','2','4')
+#define ERRCODE_ZERO_LENGTH_CHARACTER_STRING MAKE_SQLSTATE('2','2','0','0','F')
+#define ERRCODE_FLOATING_POINT_EXCEPTION MAKE_SQLSTATE('2','2','P','0','1')
+#define ERRCODE_INVALID_TEXT_REPRESENTATION MAKE_SQLSTATE('2','2','P','0','2')
+#define ERRCODE_INVALID_BINARY_REPRESENTATION MAKE_SQLSTATE('2','2','P','0','3')
+#define ERRCODE_BAD_COPY_FILE_FORMAT MAKE_SQLSTATE('2','2','P','0','4')
+#define ERRCODE_UNTRANSLATABLE_CHARACTER MAKE_SQLSTATE('2','2','P','0','5')
+#define ERRCODE_NOT_AN_XML_DOCUMENT MAKE_SQLSTATE('2','2','0','0','L')
+#define ERRCODE_INVALID_XML_DOCUMENT MAKE_SQLSTATE('2','2','0','0','M')
+#define ERRCODE_INVALID_XML_CONTENT MAKE_SQLSTATE('2','2','0','0','N')
+#define ERRCODE_INVALID_XML_COMMENT MAKE_SQLSTATE('2','2','0','0','S')
+#define ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION MAKE_SQLSTATE('2','2','0','0','T')
+#define ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE MAKE_SQLSTATE('2','2','0','3','0')
+#define ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION MAKE_SQLSTATE('2','2','0','3','1')
+#define ERRCODE_INVALID_JSON_TEXT MAKE_SQLSTATE('2','2','0','3', '2')
+#define ERRCODE_INVALID_SQL_JSON_SUBSCRIPT MAKE_SQLSTATE('2','2','0','3','3')
+#define ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','4')
+#define ERRCODE_NO_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','5')
+#define ERRCODE_NON_NUMERIC_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','6')
+#define ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT MAKE_SQLSTATE('2','2','0','3','7')
+#define ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED MAKE_SQLSTATE('2','2','0','3','8')
+#define ERRCODE_SQL_JSON_ARRAY_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','9')
+#define ERRCODE_SQL_JSON_MEMBER_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','A')
+#define ERRCODE_SQL_JSON_NUMBER_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','B')
+#define ERRCODE_SQL_JSON_OBJECT_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','C')
+#define ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS MAKE_SQLSTATE('2','2','0','3','D')
+#define ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS MAKE_SQLSTATE('2','2','0','3','E')
+#define ERRCODE_SQL_JSON_SCALAR_REQUIRED MAKE_SQLSTATE('2','2','0','3','F')
+#define ERRCODE_FOR_IGNORE_ERRORS MAKE_SQLSTATE('2','2','0','4','0')
+
+/* Class 23 - Integrity Constraint Violation */
+#define ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('2','3','0','0','0')
+#define ERRCODE_RESTRICT_VIOLATION MAKE_SQLSTATE('2','3','0','0','1')
+#define ERRCODE_NOT_NULL_VIOLATION MAKE_SQLSTATE('2','3','5','0','2')
+#define ERRCODE_FOREIGN_KEY_VIOLATION MAKE_SQLSTATE('2','3','5','0','3')
+#define ERRCODE_UNIQUE_VIOLATION MAKE_SQLSTATE('2','3','5','0','5')
+#define ERRCODE_CHECK_VIOLATION MAKE_SQLSTATE('2','3','5','1','4')
+#define ERRCODE_EXCLUSION_VIOLATION MAKE_SQLSTATE('2','3','P','0','1')
+
+/* Class 24 - Invalid Cursor State */
+#define ERRCODE_INVALID_CURSOR_STATE MAKE_SQLSTATE('2','4','0','0','0')
+
+/* Class 25 - Invalid Transaction State */
+#define ERRCODE_INVALID_TRANSACTION_STATE MAKE_SQLSTATE('2','5','0','0','0')
+#define ERRCODE_ACTIVE_SQL_TRANSACTION MAKE_SQLSTATE('2','5','0','0','1')
+#define ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE MAKE_SQLSTATE('2','5','0','0','2')
+#define ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL MAKE_SQLSTATE('2','5','0','0','8')
+#define ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','3')
+#define ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','4')
+#define ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','5')
+#define ERRCODE_READ_ONLY_SQL_TRANSACTION MAKE_SQLSTATE('2','5','0','0','6')
+#define ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED MAKE_SQLSTATE('2','5','0','0','7')
+#define ERRCODE_NO_ACTIVE_SQL_TRANSACTION MAKE_SQLSTATE('2','5','P','0','1')
+#define ERRCODE_IN_FAILED_SQL_TRANSACTION MAKE_SQLSTATE('2','5','P','0','2')
+#define ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT MAKE_SQLSTATE('2','5','P','0','3')
+
+/* Class 26 - Invalid SQL Statement Name */
+#define ERRCODE_INVALID_SQL_STATEMENT_NAME MAKE_SQLSTATE('2','6','0','0','0')
+
+/* Class 27 - Triggered Data Change Violation */
+#define ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION MAKE_SQLSTATE('2','7','0','0','0')
+
+/* Class 28 - Invalid Authorization Specification */
+#define ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION MAKE_SQLSTATE('2','8','0','0','0')
+#define ERRCODE_INVALID_PASSWORD MAKE_SQLSTATE('2','8','P','0','1')
+
+/* Class 2B - Dependent Privilege Descriptors Still Exist */
+#define ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST MAKE_SQLSTATE('2','B','0','0','0')
+#define ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST MAKE_SQLSTATE('2','B','P','0','1')
+
+/* Class 2D - Invalid Transaction Termination */
+#define ERRCODE_INVALID_TRANSACTION_TERMINATION MAKE_SQLSTATE('2','D','0','0','0')
+
+/* Class 2F - SQL Routine Exception */
+#define ERRCODE_SQL_ROUTINE_EXCEPTION MAKE_SQLSTATE('2','F','0','0','0')
+#define ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT MAKE_SQLSTATE('2','F','0','0','5')
+#define ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('2','F','0','0','2')
+#define ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED MAKE_SQLSTATE('2','F','0','0','3')
+#define ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('2','F','0','0','4')
+
+/* Class 34 - Invalid Cursor Name */
+#define ERRCODE_INVALID_CURSOR_NAME MAKE_SQLSTATE('3','4','0','0','0')
+
+/* Class 38 - External Routine Exception */
+#define ERRCODE_EXTERNAL_ROUTINE_EXCEPTION MAKE_SQLSTATE('3','8','0','0','0')
+#define ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','1')
+#define ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','2')
+#define ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED MAKE_SQLSTATE('3','8','0','0','3')
+#define ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','4')
+
+/* Class 39 - External Routine Invocation Exception */
+#define ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION MAKE_SQLSTATE('3','9','0','0','0')
+#define ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED MAKE_SQLSTATE('3','9','0','0','1')
+#define ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED MAKE_SQLSTATE('3','9','0','0','4')
+#define ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','1')
+#define ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','2')
+#define ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','3')
+
+/* Class 3B - Savepoint Exception */
+#define ERRCODE_SAVEPOINT_EXCEPTION MAKE_SQLSTATE('3','B','0','0','0')
+#define ERRCODE_S_E_INVALID_SPECIFICATION MAKE_SQLSTATE('3','B','0','0','1')
+
+/* Class 3D - Invalid Catalog Name */
+#define ERRCODE_INVALID_CATALOG_NAME MAKE_SQLSTATE('3','D','0','0','0')
+
+/* Class 3F - Invalid Schema Name */
+#define ERRCODE_INVALID_SCHEMA_NAME MAKE_SQLSTATE('3','F','0','0','0')
+
+/* Class 40 - Transaction Rollback */
+#define ERRCODE_TRANSACTION_ROLLBACK MAKE_SQLSTATE('4','0','0','0','0')
+#define ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('4','0','0','0','2')
+#define ERRCODE_T_R_SERIALIZATION_FAILURE MAKE_SQLSTATE('4','0','0','0','1')
+#define ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN MAKE_SQLSTATE('4','0','0','0','3')
+#define ERRCODE_T_R_DEADLOCK_DETECTED MAKE_SQLSTATE('4','0','P','0','1')
+
+/* Class 42 - Syntax Error or Access Rule Violation */
+#define ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION MAKE_SQLSTATE('4','2','0','0','0')
+#define ERRCODE_SYNTAX_ERROR MAKE_SQLSTATE('4','2','6','0','1')
+#define ERRCODE_INSUFFICIENT_PRIVILEGE MAKE_SQLSTATE('4','2','5','0','1')
+#define ERRCODE_CANNOT_COERCE MAKE_SQLSTATE('4','2','8','4','6')
+#define ERRCODE_GROUPING_ERROR MAKE_SQLSTATE('4','2','8','0','3')
+#define ERRCODE_WINDOWING_ERROR MAKE_SQLSTATE('4','2','P','2','0')
+#define ERRCODE_INVALID_RECURSION MAKE_SQLSTATE('4','2','P','1','9')
+#define ERRCODE_INVALID_FOREIGN_KEY MAKE_SQLSTATE('4','2','8','3','0')
+#define ERRCODE_INVALID_NAME MAKE_SQLSTATE('4','2','6','0','2')
+#define ERRCODE_NAME_TOO_LONG MAKE_SQLSTATE('4','2','6','2','2')
+#define ERRCODE_RESERVED_NAME MAKE_SQLSTATE('4','2','9','3','9')
+#define ERRCODE_DATATYPE_MISMATCH MAKE_SQLSTATE('4','2','8','0','4')
+#define ERRCODE_INDETERMINATE_DATATYPE MAKE_SQLSTATE('4','2','P','1','8')
+#define ERRCODE_COLLATION_MISMATCH MAKE_SQLSTATE('4','2','P','2','1')
+#define ERRCODE_INDETERMINATE_COLLATION MAKE_SQLSTATE('4','2','P','2','2')
+#define ERRCODE_WRONG_OBJECT_TYPE MAKE_SQLSTATE('4','2','8','0','9')
+#define ERRCODE_GENERATED_ALWAYS MAKE_SQLSTATE('4','2','8','C','9')
+#define ERRCODE_UNDEFINED_COLUMN MAKE_SQLSTATE('4','2','7','0','3')
+#define ERRCODE_UNDEFINED_CURSOR MAKE_SQLSTATE('3','4','0','0','0')
+#define ERRCODE_UNDEFINED_DATABASE MAKE_SQLSTATE('3','D','0','0','0')
+#define ERRCODE_UNDEFINED_FUNCTION MAKE_SQLSTATE('4','2','8','8','3')
+#define ERRCODE_UNDEFINED_PSTATEMENT MAKE_SQLSTATE('2','6','0','0','0')
+#define ERRCODE_UNDEFINED_SCHEMA MAKE_SQLSTATE('3','F','0','0','0')
+#define ERRCODE_UNDEFINED_TABLE MAKE_SQLSTATE('4','2','P','0','1')
+#define ERRCODE_UNDEFINED_PARAMETER MAKE_SQLSTATE('4','2','P','0','2')
+#define ERRCODE_UNDEFINED_OBJECT MAKE_SQLSTATE('4','2','7','0','4')
+#define ERRCODE_DUPLICATE_COLUMN MAKE_SQLSTATE('4','2','7','0','1')
+#define ERRCODE_DUPLICATE_CURSOR MAKE_SQLSTATE('4','2','P','0','3')
+#define ERRCODE_DUPLICATE_DATABASE MAKE_SQLSTATE('4','2','P','0','4')
+#define ERRCODE_DUPLICATE_FUNCTION MAKE_SQLSTATE('4','2','7','2','3')
+#define ERRCODE_DUPLICATE_PSTATEMENT MAKE_SQLSTATE('4','2','P','0','5')
+#define ERRCODE_DUPLICATE_SCHEMA MAKE_SQLSTATE('4','2','P','0','6')
+#define ERRCODE_DUPLICATE_TABLE MAKE_SQLSTATE('4','2','P','0','7')
+#define ERRCODE_DUPLICATE_ALIAS MAKE_SQLSTATE('4','2','7','1','2')
+#define ERRCODE_DUPLICATE_OBJECT MAKE_SQLSTATE('4','2','7','1','0')
+#define ERRCODE_AMBIGUOUS_COLUMN MAKE_SQLSTATE('4','2','7','0','2')
+#define ERRCODE_AMBIGUOUS_FUNCTION MAKE_SQLSTATE('4','2','7','2','5')
+#define ERRCODE_AMBIGUOUS_PARAMETER MAKE_SQLSTATE('4','2','P','0','8')
+#define ERRCODE_AMBIGUOUS_ALIAS MAKE_SQLSTATE('4','2','P','0','9')
+#define ERRCODE_INVALID_COLUMN_REFERENCE MAKE_SQLSTATE('4','2','P','1','0')
+#define ERRCODE_INVALID_COLUMN_DEFINITION MAKE_SQLSTATE('4','2','6','1','1')
+#define ERRCODE_INVALID_CURSOR_DEFINITION MAKE_SQLSTATE('4','2','P','1','1')
+#define ERRCODE_INVALID_DATABASE_DEFINITION MAKE_SQLSTATE('4','2','P','1','2')
+#define ERRCODE_INVALID_FUNCTION_DEFINITION MAKE_SQLSTATE('4','2','P','1','3')
+#define ERRCODE_INVALID_PSTATEMENT_DEFINITION MAKE_SQLSTATE('4','2','P','1','4')
+#define ERRCODE_INVALID_SCHEMA_DEFINITION MAKE_SQLSTATE('4','2','P','1','5')
+#define ERRCODE_INVALID_TABLE_DEFINITION MAKE_SQLSTATE('4','2','P','1','6')
+#define ERRCODE_INVALID_OBJECT_DEFINITION MAKE_SQLSTATE('4','2','P','1','7')
+
+/* Class 44 - WITH CHECK OPTION Violation */
+#define ERRCODE_WITH_CHECK_OPTION_VIOLATION MAKE_SQLSTATE('4','4','0','0','0')
+
+/* Class 53 - Insufficient Resources */
+#define ERRCODE_INSUFFICIENT_RESOURCES MAKE_SQLSTATE('5','3','0','0','0')
+#define ERRCODE_DISK_FULL MAKE_SQLSTATE('5','3','1','0','0')
+#define ERRCODE_OUT_OF_MEMORY MAKE_SQLSTATE('5','3','2','0','0')
+#define ERRCODE_TOO_MANY_CONNECTIONS MAKE_SQLSTATE('5','3','3','0','0')
+#define ERRCODE_CONFIGURATION_LIMIT_EXCEEDED MAKE_SQLSTATE('5','3','4','0','0')
+
+/* Class 54 - Program Limit Exceeded */
+#define ERRCODE_PROGRAM_LIMIT_EXCEEDED MAKE_SQLSTATE('5','4','0','0','0')
+#define ERRCODE_STATEMENT_TOO_COMPLEX MAKE_SQLSTATE('5','4','0','0','1')
+#define ERRCODE_TOO_MANY_COLUMNS MAKE_SQLSTATE('5','4','0','1','1')
+#define ERRCODE_TOO_MANY_ARGUMENTS MAKE_SQLSTATE('5','4','0','2','3')
+
+/* Class 55 - Object Not In Prerequisite State */
+#define ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE MAKE_SQLSTATE('5','5','0','0','0')
+#define ERRCODE_OBJECT_IN_USE MAKE_SQLSTATE('5','5','0','0','6')
+#define ERRCODE_CANT_CHANGE_RUNTIME_PARAM MAKE_SQLSTATE('5','5','P','0','2')
+#define ERRCODE_LOCK_NOT_AVAILABLE MAKE_SQLSTATE('5','5','P','0','3')
+#define ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE MAKE_SQLSTATE('5','5','P','0','4')
+
+/* Class 57 - Operator Intervention */
+#define ERRCODE_OPERATOR_INTERVENTION MAKE_SQLSTATE('5','7','0','0','0')
+#define ERRCODE_QUERY_CANCELED MAKE_SQLSTATE('5','7','0','1','4')
+#define ERRCODE_ADMIN_SHUTDOWN MAKE_SQLSTATE('5','7','P','0','1')
+#define ERRCODE_CRASH_SHUTDOWN MAKE_SQLSTATE('5','7','P','0','2')
+#define ERRCODE_CANNOT_CONNECT_NOW MAKE_SQLSTATE('5','7','P','0','3')
+#define ERRCODE_DATABASE_DROPPED MAKE_SQLSTATE('5','7','P','0','4')
+#define ERRCODE_IDLE_SESSION_TIMEOUT MAKE_SQLSTATE('5','7','P','0','5')
+
+/* Class 58 - System Error (errors external to PostgreSQL itself) */
+#define ERRCODE_SYSTEM_ERROR MAKE_SQLSTATE('5','8','0','0','0')
+#define ERRCODE_IO_ERROR MAKE_SQLSTATE('5','8','0','3','0')
+#define ERRCODE_UNDEFINED_FILE MAKE_SQLSTATE('5','8','P','0','1')
+#define ERRCODE_DUPLICATE_FILE MAKE_SQLSTATE('5','8','P','0','2')
+
+/* Class 72 - Snapshot Failure */
+#define ERRCODE_SNAPSHOT_TOO_OLD MAKE_SQLSTATE('7','2','0','0','0')
+
+/* Class F0 - Configuration File Error */
+#define ERRCODE_CONFIG_FILE_ERROR MAKE_SQLSTATE('F','0','0','0','0')
+#define ERRCODE_LOCK_FILE_EXISTS MAKE_SQLSTATE('F','0','0','0','1')
+
+/* Class HV - Foreign Data Wrapper Error (SQL/MED) */
+#define ERRCODE_FDW_ERROR MAKE_SQLSTATE('H','V','0','0','0')
+#define ERRCODE_FDW_COLUMN_NAME_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','5')
+#define ERRCODE_FDW_DYNAMIC_PARAMETER_VALUE_NEEDED MAKE_SQLSTATE('H','V','0','0','2')
+#define ERRCODE_FDW_FUNCTION_SEQUENCE_ERROR MAKE_SQLSTATE('H','V','0','1','0')
+#define ERRCODE_FDW_INCONSISTENT_DESCRIPTOR_INFORMATION MAKE_SQLSTATE('H','V','0','2','1')
+#define ERRCODE_FDW_INVALID_ATTRIBUTE_VALUE MAKE_SQLSTATE('H','V','0','2','4')
+#define ERRCODE_FDW_INVALID_COLUMN_NAME MAKE_SQLSTATE('H','V','0','0','7')
+#define ERRCODE_FDW_INVALID_COLUMN_NUMBER MAKE_SQLSTATE('H','V','0','0','8')
+#define ERRCODE_FDW_INVALID_DATA_TYPE MAKE_SQLSTATE('H','V','0','0','4')
+#define ERRCODE_FDW_INVALID_DATA_TYPE_DESCRIPTORS MAKE_SQLSTATE('H','V','0','0','6')
+#define ERRCODE_FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER MAKE_SQLSTATE('H','V','0','9','1')
+#define ERRCODE_FDW_INVALID_HANDLE MAKE_SQLSTATE('H','V','0','0','B')
+#define ERRCODE_FDW_INVALID_OPTION_INDEX MAKE_SQLSTATE('H','V','0','0','C')
+#define ERRCODE_FDW_INVALID_OPTION_NAME MAKE_SQLSTATE('H','V','0','0','D')
+#define ERRCODE_FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH MAKE_SQLSTATE('H','V','0','9','0')
+#define ERRCODE_FDW_INVALID_STRING_FORMAT MAKE_SQLSTATE('H','V','0','0','A')
+#define ERRCODE_FDW_INVALID_USE_OF_NULL_POINTER MAKE_SQLSTATE('H','V','0','0','9')
+#define ERRCODE_FDW_TOO_MANY_HANDLES MAKE_SQLSTATE('H','V','0','1','4')
+#define ERRCODE_FDW_OUT_OF_MEMORY MAKE_SQLSTATE('H','V','0','0','1')
+#define ERRCODE_FDW_NO_SCHEMAS MAKE_SQLSTATE('H','V','0','0','P')
+#define ERRCODE_FDW_OPTION_NAME_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','J')
+#define ERRCODE_FDW_REPLY_HANDLE MAKE_SQLSTATE('H','V','0','0','K')
+#define ERRCODE_FDW_SCHEMA_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','Q')
+#define ERRCODE_FDW_TABLE_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','R')
+#define ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION MAKE_SQLSTATE('H','V','0','0','L')
+#define ERRCODE_FDW_UNABLE_TO_CREATE_REPLY MAKE_SQLSTATE('H','V','0','0','M')
+#define ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION MAKE_SQLSTATE('H','V','0','0','N')
+
+/* Class P0 - PL/pgSQL Error */
+#define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0','0','0','0')
+#define ERRCODE_RAISE_EXCEPTION MAKE_SQLSTATE('P','0','0','0','1')
+#define ERRCODE_NO_DATA_FOUND MAKE_SQLSTATE('P','0','0','0','2')
+#define ERRCODE_TOO_MANY_ROWS MAKE_SQLSTATE('P','0','0','0','3')
+#define ERRCODE_ASSERT_FAILURE MAKE_SQLSTATE('P','0','0','0','4')
+
+/* Class XX - Internal Error */
+#define ERRCODE_INTERNAL_ERROR MAKE_SQLSTATE('X','X','0','0','0')
+#define ERRCODE_DATA_CORRUPTED MAKE_SQLSTATE('X','X','0','0','1')
+#define ERRCODE_INDEX_CORRUPTED MAKE_SQLSTATE('X','X','0','0','2')
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 2f412ca3db..855cbeb401 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2545,7 +2545,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index 264895d278..ade74ce5a1 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -31,6 +31,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
bool header_line; /* CSV header line? */
char *null_print; /* NULL marker string (server encoding!) */
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index 4d68d9cceb..93a3b74999 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -68,6 +68,7 @@ typedef struct CopyFromStateData
/* parameters from the COPY command */
Relation rel; /* relation to copy from */
List *attnumlist; /* integer list of attnums to copy */
+ int attr_count; /* length of attnumlist */
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index f836acf876..2bb3cccea9 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -196,6 +196,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..4e04efcbba 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,37 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- test IGNORE_ERRORS option
+CREATE TABLE check_ign_err (n int, m int, k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 3 | 3 | 3
+(2 rows)
+
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2"
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 3 | 3 | 3
+(2 rows)
+
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2, column m: "a"
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 3 | 3 | 3
+(2 rows)
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
@@ -663,3 +694,4 @@ DROP TABLE instead_of_insert_tbl;
DROP VIEW instead_of_insert_tbl_view;
DROP VIEW instead_of_insert_tbl_view_2;
DROP FUNCTION fun_instead_of_insert_tbl();
+DROP TABLE check_ign_err;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..3642c11f91 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,31 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- test IGNORE_ERRORS option
+CREATE TABLE check_ign_err (n int, m int, k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3 3
+\.
+SELECT * FROM check_ign_err;
+
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2
+3 3 3
+\.
+SELECT * FROM check_ign_err;
+
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 a 2
+3 3 3
+\.
+SELECT * FROM check_ign_err;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
@@ -468,3 +493,4 @@ DROP TABLE instead_of_insert_tbl;
DROP VIEW instead_of_insert_tbl_view;
DROP VIEW instead_of_insert_tbl_view_2;
DROP FUNCTION fun_instead_of_insert_tbl();
+DROP TABLE check_ign_err;
--
2.25.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2021-12-19 05:09 ` Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Pavel Stehule @ 2021-12-19 05:09 UTC (permalink / raw)
To: Damir Belyalov <[email protected]>; +Cc: pgsql-hackers
Hi
so 18. 12. 2021 v 9:55 odesílatel Damir Belyalov <[email protected]>
napsal:
> Hello.
>
> Wrote a patch implementing COPY with ignoring errors in rows using block
> subtransactions.
>
It is great so you are working on this patch. Unfortunately, I am afraid
this simple design is not optimal. Using subtransaction for every row has
too big overhead. I think it should use subtransaction for blocks of rows
(1000 rows), and only when there is an exception, then it should replay
inserts in subtransaction per row. You should check performance overhead.
Regards
Pavel
> Syntax: COPY [table] FROM [file/stdin] WITH IGNORE_ERROS;
>
> Examples:
> CREATE TABLE check_ign_err (n int, m int, k int);
> COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
> 1 1 1
> 2 2 2 2
> 3 3 3
> \.
> WARNING: COPY check_ign_err, line 2: "2 2 2 2"
> SELECT * FROM check_ign_err;
> n | m | k
> ---+---+---
> 1 | 1 | 1
> 3 | 3 | 3
> (2 rows)
>
> ##################################################
>
> TRUNCATE check_ign_err;
> COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
> 1 1 1
> 2 2
> 3 3 3
> \.
> WARNING: COPY check_ign_err, line 2: "2 2"
> SELECT * FROM check_ign_err;
> n | m | k
> ---+---+---
> 1 | 1 | 1
> 3 | 3 | 3
> (2 rows)
>
> ##################################################
>
> TRUNCATE check_ign_err;
> COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
> 1 1 1
> 2 a 2
> 3 3 3
> \.
> WARNING: COPY check_ign_err, line 2, column m: "a"
> SELECT * FROM check_ign_err;
> n | m | k
> ---+---+---
> 1 | 1 | 1
> 3 | 3 | 3
> (2 rows)
>
>
>
> Regards, Damir
>
> пт, 10 дек. 2021 г. в 21:48, Pavel Stehule <[email protected]>:
>
>>
>>
>> 2014-12-26 11:41 GMT+01:00 Pavel Stehule <[email protected]>:
>>
>>>
>>>
>>> 2014-12-25 22:23 GMT+01:00 Alex Shulgin <[email protected]>:
>>>
>>>> Trent Shipley <[email protected]> writes:
>>>>
>>>> > On Friday 2007-12-14 16:22, Tom Lane wrote:
>>>> >> Neil Conway <[email protected]> writes:
>>>> >> > By modifying COPY: COPY IGNORE ERRORS or some such would instruct
>>>> COPY
>>>> >> > to drop (and log) rows that contain malformed data. That is, rows
>>>> with
>>>> >> > too many or too few columns, rows that result in constraint
>>>> violations,
>>>> >> > and rows containing columns where the data type's input function
>>>> raises
>>>> >> > an error. The last case is the only thing that would be a bit
>>>> tricky to
>>>> >> > implement, I think: you could use PG_TRY() around the
>>>> InputFunctionCall,
>>>> >> > but I guess you'd need a subtransaction to ensure that you reset
>>>> your
>>>> >> > state correctly after catching an error.
>>>> >>
>>>> >> Yeah. It's the subtransaction per row that's daunting --- not only
>>>> the
>>>> >> cycles spent for that, but the ensuing limitation to 4G rows imported
>>>> >> per COPY.
>>>> >
>>>> > You could extend the COPY FROM syntax with a COMMIT EVERY n clause.
>>>> This
>>>> > would help with the 4G subtransaction limit. The cost to the ETL
>>>> process is
>>>> > that a simple rollback would not be guaranteed send the process back
>>>> to it's
>>>> > initial state. There are easy ways to deal with the rollback issue
>>>> though.
>>>> >
>>>> > A {NO} RETRY {USING algorithm} clause might be useful. If the NO
>>>> RETRY
>>>> > option is selected then the COPY FROM can run without subtransactions
>>>> and in
>>>> > excess of the 4G per transaction limit. NO RETRY should be the
>>>> default since
>>>> > it preserves the legacy behavior of COPY FROM.
>>>> >
>>>> > You could have an EXCEPTIONS TO {filename|STDERR} clause. I would not
>>>> give the
>>>> > option of sending exceptions to a table since they are presumably
>>>> malformed,
>>>> > otherwise they would not be exceptions. (Users should re-process
>>>> exception
>>>> > files if they want an if good then table a else exception to table b
>>>> ...)
>>>> >
>>>> > EXCEPTIONS TO and NO RETRY would be mutually exclusive.
>>>> >
>>>> >
>>>> >> If we could somehow only do a subtransaction per failure, things
>>>> would
>>>> >> be much better, but I don't see how.
>>>>
>>>> Hello,
>>>>
>>>> Attached is a proof of concept patch for this TODO item. There is no
>>>> docs yet, I just wanted to know if approach is sane.
>>>>
>>>> The added syntax is like the following:
>>>>
>>>> COPY [table] FROM [file/program/stdin] EXCEPTIONS TO [file or stdout]
>>>>
>>>> The way it's done it is abusing Copy Both mode and from my limited
>>>> testing, that seems to just work. The error trapping itself is done
>>>> using PG_TRY/PG_CATCH and can only catch formatting or before-insert
>>>> trigger errors, no attempt is made to recover from a failed unique
>>>> constraint, etc.
>>>>
>>>> Example in action:
>>>>
>>>> postgres=# \d test_copy2
>>>> Table "public.test_copy2"
>>>> Column | Type | Modifiers
>>>> --------+---------+-----------
>>>> id | integer |
>>>> val | integer |
>>>>
>>>> postgres=# copy test_copy2 from program 'seq 3' exceptions to stdout;
>>>> 1
>>>> NOTICE: missing data for column "val"
>>>> CONTEXT: COPY test_copy2, line 1: "1"
>>>> 2
>>>> NOTICE: missing data for column "val"
>>>> CONTEXT: COPY test_copy2, line 2: "2"
>>>> 3
>>>> NOTICE: missing data for column "val"
>>>> CONTEXT: COPY test_copy2, line 3: "3"
>>>> NOTICE: total exceptions ignored: 3
>>>>
>>>> postgres=# \d test_copy1
>>>> Table "public.test_copy1"
>>>> Column | Type | Modifiers
>>>> --------+---------+-----------
>>>> id | integer | not null
>>>>
>>>> postgres=# set client_min_messages to warning;
>>>> SET
>>>> postgres=# copy test_copy1 from program 'ls /proc' exceptions to stdout;
>>>> ...
>>>> vmstat
>>>> zoneinfo
>>>> postgres=#
>>>>
>>>> Limited performance testing shows no significant difference between
>>>> error-catching and plain code path. For example, timing
>>>>
>>>> copy test_copy1 from program 'seq 1000000' [exceptions to stdout]
>>>>
>>>> shows similar numbers with or without the added "exceptions to" clause.
>>>>
>>>> Now that I'm sending this I wonder if the original comment about the
>>>> need for subtransaction around every loaded line still holds. Any
>>>> example of what would be not properly rolled back by just PG_TRY?
>>>>
>>>
>>> this method is unsafe .. exception handlers doesn't free memory usually
>>> - there is risk of memory leaks, source leaks
>>>
>>> you can enforce same performance with block subtransactions - when you
>>> use subtransaction for 1000 rows, then impact of subtransactions is minimal
>>>
>>> when block fails, then you can use row level subtransaction - it works
>>> well when you expect almost correct data.
>>>
>>
>> Two years ago I wrote a extension that did it - but I have not time to
>> finish it and push to upstream.
>>
>> Regards
>>
>> Pavel
>>
>>
>>>
>>> Regards
>>>
>>> Pavel
>>>
>>>
>>>>
>>>> Happy hacking!
>>>> --
>>>> Alex
>>>>
>>>>
>>>>
>>>> --
>>>> Sent via pgsql-hackers mailing list ([email protected])
>>>> To make changes to your subscription:
>>>> http://www.postgresql.org/mailpref/pgsql-hackers
>>>>
>>>>
>>>
>>
>> --
>> Sent via pgsql-hackers mailing list ([email protected])
>> To make changes to your subscription:
>> http://www.postgresql.org/mailpref/pgsql-hackers
>>
>
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
@ 2022-07-19 12:40 ` Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2022-07-19 12:40 UTC (permalink / raw)
To: pgsql-hackers; [email protected]
Hi!
Improved my patch by adding block subtransactions.
The block size is determined by the REPLAY_BUFFER_SIZE parameter.
I used the idea of a buffer for accumulating tuples in it.
If we read REPLAY_BUFFER_SIZE rows without errors, the subtransaction will
be committed.
If we find an error, the subtransaction will rollback and the buffer will
be replayed containing tuples.
In the patch REPLAY_BUFFER_SIZE equals 3, but it can be changed to any
other number (for example 1000).
There is an idea to create a GUC parameter for it.
Also maybe create a GUC parameter for the number of occurring WARNINGS by
rows with errors.
For CIM_MULTI and CIM_MULTI_CONDITIONAL cases the buffer is not needed.
It is needed for the CIM_SINGLE case.
Tests:
-- CIM_MULTI case
CREATE TABLE check_ign_err (n int, m int, k int);
COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
WARNING: COPY check_ign_err, line 2: "2 2 2 2"
WARNING: COPY check_ign_err, line 3: "3 3"
WARNING: COPY check_ign_err, line 4, column n: "a"
WARNING: COPY check_ign_err, line 5, column m: "b"
WARNING: COPY check_ign_err, line 6, column n: ""
1 1 1
2 2 2 2
3 3
a 4 4
5 b b
7 7 7
\.
SELECT * FROM check_ign_err;
WARNING: COPY check_ign_err, line 2: "2 2 2 2"
WARNING: COPY check_ign_err, line 3: "3 3"
WARNING: COPY check_ign_err, line 4, column n: "a"
WARNING: COPY check_ign_err, line 5, column m: "b"
WARNING: COPY check_ign_err, line 6, column n: ""
n | m | k
---+---+---
1 | 1 | 1
7 | 7 | 7
(2 rows)
##################################################
-- CIM_SINGLE case
-- BEFORE row trigger
CREATE TABLE trig_test(n int, m int);
CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
BEGIN
INSERT INTO trig_test VALUES(NEW.n, NEW.m);
RETURN NEW;
END;
' LANGUAGE plpgsql;
CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
WARNING: COPY check_ign_err, line 2: "2 2 2 2"
WARNING: COPY check_ign_err, line 3: "3 3"
WARNING: COPY check_ign_err, line 4, column n: "a"
WARNING: COPY check_ign_err, line 5, column m: "b"
WARNING: COPY check_ign_err, line 6, column n: ""
1 1 1
2 2 2 2
3 3
a 4 4
5 b b
7 7 7
\.
SELECT * FROM check_ign_err;
n | m | k
---+---+---
1 | 1 | 1
7 | 7 | 7
(2 rows)
##################################################
-- INSTEAD OF row trigger
CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
BEGIN
INSERT INTO check_ign_err VALUES(NEW.n, NEW.m, NEW.k);
RETURN NEW;
END;
' LANGUAGE plpgsql;
CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS;
WARNING: COPY check_ign_err, line 2: "2 2 2 2"
WARNING: COPY check_ign_err, line 3: "3 3"
WARNING: COPY check_ign_err, line 4, column n: "a"
WARNING: COPY check_ign_err, line 5, column m: "b"
WARNING: COPY check_ign_err, line 6, column n: ""
SELECT * FROM check_ign_err;
1 1 1
2 2 2 2
3 3
a 4 4
5 b b
7 7 7
\.
SELECT * FROM check_ign_err_view;
n | m | k
---+---+---
1 | 1 | 1
7 | 7 | 7
(2 rows)
##################################################
-- foreign table case in postgres_fdw extension
##################################################
-- volatile function in WHERE clause
COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
WHERE n = floor(random()*(1-1+1))+1; /* find values equal 1 */
WARNING: COPY check_ign_err, line 2: "2 2 2 2"
WARNING: COPY check_ign_err, line 3: "3 3"
WARNING: COPY check_ign_err, line 4, column n: "a"
WARNING: COPY check_ign_err, line 5, column m: "b"
WARNING: COPY check_ign_err, line 6, column n: ""
SELECT * FROM check_ign_err;
1 1 1
2 2 2 2
3 3
a 4 4
5 b b
7 7 7
\.
SELECT * FROM check_ign_err;
n | m | k
---+---+---
1 | 1 | 1
(1 row)
##################################################
-- CIM_MULTI_CONDITIONAL case
-- INSERT triggers for partition tables
CREATE TABLE check_ign_err (n int, m int, k int) PARTITION BY RANGE (n);
CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
FOR VALUES FROM (1) TO (4);
CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
FOR VALUES FROM (4) TO (8);
CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
BEGIN
INSERT INTO trig_test VALUES(NEW.n, NEW.m);
RETURN NEW;
END;
' LANGUAGE plpgsql;
CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
WARNING: COPY check_ign_err, line 2: "2 2 2 2"
WARNING: COPY check_ign_err, line 3: "3 3"
WARNING: COPY check_ign_err, line 4, column n: "a"
WARNING: COPY check_ign_err, line 5, column m: "b"
WARNING: COPY check_ign_err, line 6, column n: ""
SELECT * FROM check_ign_err;
1 1 1
2 2 2 2
3 3
a 4 4
5 b b
7 7 7
\.
n | m | k
---+---+---
1 | 1 | 1
7 | 7 | 7
(2 rows)
Thanks for feedback.
Regards, Damir
Attachments:
[application/x-patch] 0002-COPY-IGNORE_ERRORS.patch (17.3K, ../../CALH1LgvmNcnO8dYyckcEmiJ6PGDnpRWA3V1td1SDKzqt6FrMJw@mail.gmail.com/3-0002-COPY-IGNORE_ERRORS.patch)
download | inline diff:
From 6bf2168cd962b3cce666a2cabf082f558eec848c Mon Sep 17 00:00:00 2001
From: Damir Belyalov <[email protected]>
Date: Fri, 15 Oct 2021 11:55:18 +0300
Subject: [PATCH] COPY IGNORE_ERRORS
---
doc/src/sgml/ref/copy.sgml | 13 +++
src/backend/commands/copy.c | 8 ++
src/backend/commands/copyfrom.c | 138 +++++++++++++++++++++++++++-
src/backend/parser/gram.y | 8 +-
src/bin/psql/tab-complete.c | 3 +-
src/include/commands/copy.h | 1 +
src/include/parser/kwlist.h | 1 +
src/test/regress/expected/copy2.out | 118 ++++++++++++++++++++++++
src/test/regress/sql/copy2.sql | 110 ++++++++++++++++++++++
9 files changed, 395 insertions(+), 5 deletions(-)
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 8aae711b3b..7d20b1649e 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,18 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drop rows that contain malformed data while copying. That is rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows that result in constraint violations, rows containing columns where
+ the data type's input function raises an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 3ac731803b..fead1aba46 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -402,6 +402,7 @@ ProcessCopyOptions(ParseState *pstate,
{
bool format_specified = false;
bool freeze_specified = false;
+ bool ignore_errors_specified = false;
bool header_specified = false;
ListCell *option;
@@ -442,6 +443,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index a976008b3d..b994697b9d 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -535,6 +535,7 @@ CopyFrom(CopyFromState cstate)
ExprContext *econtext;
TupleTableSlot *singleslot = NULL;
MemoryContext oldcontext = CurrentMemoryContext;
+ ResourceOwner oldowner = CurrentResourceOwner;
PartitionTupleRouting *proute = NULL;
ErrorContextCallback errcallback;
@@ -549,6 +550,17 @@ CopyFrom(CopyFromState cstate)
bool has_instead_insert_row_trig;
bool leafpart_use_multi_insert = false;
+ /* variables for copy from ignore_errors option */
+#define REPLAY_BUFFER_SIZE 3
+ HeapTuple replay_buffer[REPLAY_BUFFER_SIZE];
+ HeapTuple replay_tuple;
+ int saved_tuples = 0;
+ int replayed_tuples = 0;
+ bool replay_is_active = false;
+ bool begin_subtransaction = true;
+ bool find_error = false;
+ bool last_replaying = false;
+
Assert(cstate->rel);
Assert(list_length(cstate->range_table) == 1);
@@ -855,9 +867,129 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
- break;
+ /*
+ * If option IGNORE_ERRORS is enabled, COPY skip rows with errors.
+ * NextCopyFrom() directly store the values/nulls array in the slot.
+ */
+ if (cstate->opts.ignore_errors)
+ {
+ bool valid_row = true;
+ bool skip_row = false;
+
+ PG_TRY();
+ {
+ if (!replay_is_active)
+ {
+ if (begin_subtransaction)
+ {
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = oldowner;
+ }
+
+ if (saved_tuples < REPLAY_BUFFER_SIZE)
+ {
+ valid_row = NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+ if (valid_row)
+ {
+ if (insertMethod == CIM_SINGLE)
+ {
+ MemoryContextSwitchTo(oldcontext);
+
+ replay_tuple = heap_form_tuple(RelationGetDescr(cstate->rel), myslot->tts_values, myslot->tts_isnull);
+ replay_buffer[saved_tuples++] = replay_tuple;
+
+ if (find_error)
+ skip_row = true;
+ }
+
+ begin_subtransaction = false;
+ }
+ }
+ else
+ {
+ ReleaseCurrentSubTransaction();
+
+ replay_is_active = true;
+ begin_subtransaction = true;
+ skip_row = true;
+ }
+ }
+ else
+ {
+ if (insertMethod == CIM_SINGLE && find_error && replayed_tuples < saved_tuples)
+ {
+ heap_deform_tuple(replay_buffer[replayed_tuples], RelationGetDescr(cstate->rel), myslot->tts_values, myslot->tts_isnull);
+ replayed_tuples++;
+ }
+ else
+ {
+ MemSet(replay_buffer, 0, REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ saved_tuples = 0;
+ replayed_tuples = 0;
+
+ replay_is_active = false;
+ find_error = false;
+ skip_row = true;
+ }
+ }
+ }
+ PG_CATCH();
+ {
+ ErrorData *errdata;
+ MemoryContextSwitchTo(oldcontext);
+ errdata = CopyErrorData();
+
+ switch (errdata->sqlerrcode)
+ {
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ RollbackAndReleaseCurrentSubTransaction();
+ elog(WARNING, "%s", errdata->context);
+
+ begin_subtransaction = true;
+ find_error = true;
+ skip_row = true;
+
+ break;
+
+ default:
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+ }
+ PG_END_TRY();
+
+ if (!valid_row)
+ {
+ if (!last_replaying)
+ {
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = oldowner;
+
+ if (replayed_tuples < saved_tuples)
+ {
+ replay_is_active = true;
+ skip_row = true;
+ last_replaying = true;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ if (skip_row)
+ continue;
+ }
+ else
+ {
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
+ }
ExecStoreVirtualTuple(myslot);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index df5ceea910..3bb7235b34 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -800,7 +800,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3456,6 +3456,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeInteger(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -17814,6 +17818,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -18393,6 +18398,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index e572f585ef..feaf18b043 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2742,7 +2742,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index cb0096aeb6..2b696f99bc 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -42,6 +42,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index ae35f03251..2af11bd359 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -201,6 +201,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..74827ecca0 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,124 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int, k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+-- CIM_SINGLE case
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO check_ign_err VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err_view, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 3"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column m: "b"
+WARNING: COPY check_ign_err_view, line 6, column n: ""
+SELECT * FROM check_ign_err_view;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* find values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int, k int) PARTITION BY RANGE (n);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (8);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..7eee78bccd 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,116 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int, k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE case
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO check_ign_err VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err_view;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* find values equal 1 */
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int, k int) PARTITION BY RANGE (n);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (8);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
--
2.25.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-08-15 12:29 ` torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: torikoshia @ 2022-08-15 12:29 UTC (permalink / raw)
To: Damir Belyalov <[email protected]>; +Cc: pgsql-hackers
On 2022-07-19 21:40, Damir Belyalov wrote:
> Hi!
>
> Improved my patch by adding block subtransactions.
> The block size is determined by the REPLAY_BUFFER_SIZE parameter.
> I used the idea of a buffer for accumulating tuples in it.
> If we read REPLAY_BUFFER_SIZE rows without errors, the subtransaction
> will be committed.
> If we find an error, the subtransaction will rollback and the buffer
> will be replayed containing tuples.
Thanks for working on this!
I tested 0002-COPY-IGNORE_ERRORS.patch and faced an unexpected behavior.
I loaded 10000 rows which contained 1 wrong row.
I expected I could see 9999 rows after COPY, but just saw 999 rows.
Since when I changed MAX_BUFFERED_TUPLES from 1000 to other values, the
number of loaded rows also changed, I imagine MAX_BUFFERED_TUPLES might
be giving influence of this behavior.
```sh
$ cat /tmp/test10000.dat
1 aaa
2 aaa
3 aaa
4 aaa
5 aaa
6 aaa
7 aaa
8 aaa
9 aaa
10 aaa
11 aaa
...
9994 aaa
9995 aaa
9996 aaa
9997 aaa
9998 aaa
9999 aaa
xxx aaa
```
```SQL
=# CREATE TABLE test (id int, data text);
=# COPY test FROM '/tmp/test10000.dat' WITH (IGNORE_ERRORS);
WARNING: COPY test, line 10000, column i: "xxx"
COPY 9999
=# SELECT COUNT(*) FROM test;
count
-------
999
(1 row)
```
BTW I may be overlooking it, but have you submit this proposal to the
next CommitFest?
https://commitfest.postgresql.org/39/
--
Regards,
--
Atsushi Torikoshi
NTT DATA CORPORATION
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
@ 2022-08-15 13:23 ` Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2022-08-15 13:23 UTC (permalink / raw)
To: torikoshia <[email protected]>; +Cc: pgsql-hackers; [email protected]
>
>
> Thank you for feedback.
I improved my patch recently and tested it on different sizes of
MAX_BUFFERED_TUPLES and REPLAY_BUFFER_SIZE.
> I loaded 10000 rows which contained 1 wrong row.
> I expected I could see 9999 rows after COPY, but just saw 999 rows.
Also I implemented your case and it worked correctly.
> BTW I may be overlooking it, but have you submit this proposal to the
next CommitFest?
Good idea. Haven't done it yet.
Regards,
Damir
Postgres Professional
Attachments:
[text/x-patch] 0003-COPY_IGNORE_ERRORS.patch (20.8K, ../../CALH1Lgu0dqsQUm9QYdoSvgu-O9Ac5OsbE3TxxZqChUrVF+Qrjw@mail.gmail.com/3-0003-COPY_IGNORE_ERRORS.patch)
download | inline diff:
From fa6b99c129eb890b25f006bb7891a247c8a431a7 Mon Sep 17 00:00:00 2001
From: Damir Belyalov <[email protected]>
Date: Fri, 15 Oct 2021 11:55:18 +0300
Subject: [PATCH] COPY_IGNORE_ERRORS without GUC with function
safeNextCopyFrom() with struct SafeCopyFromState with refactoring
---
doc/src/sgml/ref/copy.sgml | 13 ++
src/backend/commands/copy.c | 8 ++
src/backend/commands/copyfrom.c | 162 ++++++++++++++++++++++-
src/backend/parser/gram.y | 8 +-
src/bin/psql/tab-complete.c | 3 +-
src/include/commands/copy.h | 1 +
src/include/commands/copyfrom_internal.h | 21 +++
src/include/parser/kwlist.h | 1 +
src/test/regress/expected/copy2.out | 123 +++++++++++++++++
src/test/regress/sql/copy2.sql | 110 +++++++++++++++
10 files changed, 445 insertions(+), 5 deletions(-)
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 8aae711b3b..7d20b1649e 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,18 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drop rows that contain malformed data while copying. That is rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows that result in constraint violations, rows containing columns where
+ the data type's input function raises an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 3ac731803b..fead1aba46 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -402,6 +402,7 @@ ProcessCopyOptions(ParseState *pstate,
{
bool format_specified = false;
bool freeze_specified = false;
+ bool ignore_errors_specified = false;
bool header_specified = false;
ListCell *option;
@@ -442,6 +443,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index a976008b3d..285c491ddd 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -106,6 +106,9 @@ static char *limit_printout_length(const char *str);
static void ClosePipeFromProgram(CopyFromState cstate);
+static bool safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext,
+ Datum *values, bool *nulls);
+
/*
* error context callback for COPY FROM
*
@@ -521,6 +524,125 @@ CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
miinfo->bufferedBytes += tuplen;
}
+/*
+ * Analog of NextCopyFrom() but ignore rows with errors while copying.
+ */
+static bool
+safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
+{
+ SafeCopyFromState *safecstate = cstate->safecstate;
+ bool valid_row = true;
+
+ safecstate->skip_row = false;
+
+ PG_TRY();
+ {
+ if (!safecstate->replay_is_active)
+ {
+ if (safecstate->begin_subtransaction)
+ {
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = safecstate->oldowner;
+
+ safecstate->begin_subtransaction = false;
+ }
+
+ if (safecstate->saved_tuples < REPLAY_BUFFER_SIZE)
+ {
+ valid_row = NextCopyFrom(cstate, econtext, values, nulls);
+ if (valid_row)
+ {
+ /* Fill replay_buffer in oldcontext*/
+ MemoryContextSwitchTo(safecstate->oldcontext);
+ safecstate->replay_buffer[safecstate->saved_tuples++] = heap_form_tuple(RelationGetDescr(cstate->rel), values, nulls);
+
+ safecstate->skip_row = true;
+ }
+ else if (!safecstate->processed_remaining_tuples)
+ {
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = safecstate->oldowner;
+ if (safecstate->replayed_tuples < safecstate->saved_tuples)
+ {
+ /* Prepare to replay remaining tuples if they exist */
+ safecstate->replay_is_active = true;
+ safecstate->processed_remaining_tuples = true;
+ safecstate->skip_row = true;
+ return true;
+ }
+ }
+ }
+ else
+ {
+ /* Buffer was filled, commit subtransaction and prepare to replay */
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = safecstate->oldowner;
+
+ safecstate->replay_is_active = true;
+ safecstate->begin_subtransaction = true;
+ safecstate->skip_row = true;
+ }
+ }
+ else
+ {
+ if (safecstate->replayed_tuples < safecstate->saved_tuples)
+ {
+ /* Replaying tuple */
+ heap_deform_tuple(safecstate->replay_buffer[safecstate->replayed_tuples++], RelationGetDescr(cstate->rel), values, nulls);
+ }
+ else
+ {
+ /* Clean up replay_buffer */
+ MemSet(safecstate->replay_buffer, 0, REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ safecstate->saved_tuples = safecstate->replayed_tuples = 0;
+
+ safecstate->replay_is_active = false;
+ safecstate->skip_row = true;
+ }
+ }
+ }
+ PG_CATCH();
+ {
+ ErrorData *errdata;
+ MemoryContextSwitchTo(safecstate->oldcontext);
+ errdata = CopyErrorData();
+
+ switch (errdata->sqlerrcode)
+ {
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = safecstate->oldowner;
+
+ safecstate->errors++;
+ if (safecstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+
+ safecstate->begin_subtransaction = true;
+ safecstate->skip_row = true;
+ break;
+ default:
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+ }
+ PG_END_TRY();
+
+ if (!valid_row)
+ {
+ ereport(WARNING,
+ errmsg("FIND %d ERRORS", safecstate->errors));
+ return false;
+ }
+
+ return true;
+}
+
/*
* Copy FROM file to relation.
*/
@@ -535,6 +657,7 @@ CopyFrom(CopyFromState cstate)
ExprContext *econtext;
TupleTableSlot *singleslot = NULL;
MemoryContext oldcontext = CurrentMemoryContext;
+ ResourceOwner oldowner = CurrentResourceOwner;
PartitionTupleRouting *proute = NULL;
ErrorContextCallback errcallback;
@@ -819,6 +942,23 @@ CopyFrom(CopyFromState cstate)
errcallback.previous = error_context_stack;
error_context_stack = &errcallback;
+ /* Initialize safeCopyFromState for IGNORE_ERRORS option*/
+ if (cstate->opts.ignore_errors)
+ {
+ cstate->safecstate = palloc(sizeof(SafeCopyFromState));
+
+ cstate->safecstate->saved_tuples = 0;
+ cstate->safecstate->replayed_tuples = 0;
+ cstate->safecstate->errors = 0;
+ cstate->safecstate->replay_is_active = false;
+ cstate->safecstate->begin_subtransaction = true;
+ cstate->safecstate->processed_remaining_tuples = false;
+
+ cstate->safecstate->oldowner = oldowner;
+ cstate->safecstate->oldcontext = oldcontext;
+ cstate->safecstate->insertMethod = insertMethod;
+ }
+
for (;;)
{
TupleTableSlot *myslot;
@@ -855,9 +995,25 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
- break;
+ /*
+ * If option IGNORE_ERRORS is enabled, COPY skips rows with errors.
+ * NextCopyFrom() directly store the values/nulls array in the slot.
+ */
+ if (cstate->safecstate)
+ {
+ bool valid_row = safeNextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+
+ /* Cannot continue or break in PG_TRY in safeNextCopyFrom() */
+ if (cstate->safecstate->skip_row)
+ continue;
+ if (!valid_row)
+ break;
+ }
+ else
+ {
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
+ }
ExecStoreVirtualTuple(myslot);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index df5ceea910..3bb7235b34 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -800,7 +800,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3456,6 +3456,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeInteger(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -17814,6 +17818,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -18393,6 +18398,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index e572f585ef..feaf18b043 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2742,7 +2742,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index cb0096aeb6..2b696f99bc 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -42,6 +42,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index 3df1c5a97c..d9d3af1fb4 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -16,6 +16,8 @@
#include "commands/copy.h"
#include "commands/trigger.h"
+#include "utils/resowner.h"
+
/*
* Represents the different source cases we need to worry about at
@@ -49,6 +51,24 @@ typedef enum CopyInsertMethod
CIM_MULTI_CONDITIONAL /* use table_multi_insert only if valid */
} CopyInsertMethod;
+/* Struct that holding fields for ignore_errors option. */
+typedef struct SafeCopyFromState
+{
+#define REPLAY_BUFFER_SIZE 1000
+ HeapTuple replay_buffer[REPLAY_BUFFER_SIZE]; /* accumulates tuples for replaying it after an error */
+ int saved_tuples; /* # of tuples in replay_buffer */
+ int replayed_tuples; /* # of tuples was replayed from buffer */
+ int errors; /* total # of errors */
+ bool replay_is_active;
+ bool begin_subtransaction;
+ bool processed_remaining_tuples; /* for case of replaying last tuples */
+ bool skip_row;
+
+ MemoryContext oldcontext;
+ ResourceOwner oldowner;
+ CopyInsertMethod insertMethod;
+} SafeCopyFromState;
+
/*
* This struct contains all the state variables used throughout a COPY FROM
* operation.
@@ -71,6 +91,7 @@ typedef struct CopyFromStateData
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
+ SafeCopyFromState *safecstate; /* struct for ignore_errors option */
CopyFormatOptions opts;
bool *convert_select_flags; /* per-column CSV/TEXT CS flags */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index ae35f03251..2af11bd359 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -201,6 +201,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..ab1f059a02 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,129 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int, k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: FIND 5 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+-- CIM_SINGLE case
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: FIND 5 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO check_ign_err VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err_view, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 3"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column m: "b"
+WARNING: COPY check_ign_err_view, line 6, column n: ""
+WARNING: FIND 5 ERRORS
+SELECT * FROM check_ign_err_view;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* find values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: FIND 5 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int, k int) PARTITION BY RANGE (n);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (8);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 2 2 2"
+WARNING: COPY check_ign_err, line 3: "3 3"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column m: "b"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: FIND 5 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+---+---
+ 1 | 1 | 1
+ 7 | 7 | 7
+(2 rows)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..7eee78bccd 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,116 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int, k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE case
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO check_ign_err VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err_view;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* find values equal 1 */
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int, k int) PARTITION BY RANGE (n);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (8);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 1 1
+2 2 2 2
+3 3
+a 4 4
+5 b b
+
+7 7 7
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
--
2.25.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-08-22 12:46 ` torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: torikoshia @ 2022-08-22 12:46 UTC (permalink / raw)
To: Damir Belyalov <[email protected]>; +Cc: pgsql-hackers; [email protected]
On 2022-08-15 22:23, Damir Belyalov wrote:
>> I expected I could see 9999 rows after COPY, but just saw 999 rows.
> Also I implemented your case and it worked correctly.
Thanks for the new patch!
Here are some comments on it.
> + if (safecstate->saved_tuples < REPLAY_BUFFER_SIZE)
> + {
> + valid_row = NextCopyFrom(cstate, econtext, values,
> nulls);
> + if (valid_row)
> + {
> + /* Fill replay_buffer in oldcontext*/
> + MemoryContextSwitchTo(safecstate->oldcontext);
> +
> safecstate->replay_buffer[safecstate->saved_tuples++] =
> heap_form_tuple(RelationGetDescr(cstate->rel), values, nulls);
>
> + /* Buffer was filled, commit subtransaction and prepare
> to replay */
> + ReleaseCurrentSubTransaction();
What is actually being committed by this ReleaseCurrentSubTransaction()?
It seems to me that just safecstate->replay_buffer is fulfilled before
this commit.
As a test, I rewrote this ReleaseCurrentSubTransaction() to
RollbackAndReleaseCurrentSubTransaction() and COPYed over 1000 rows of
data, but same data were loaded.
> +#define REPLAY_BUFFER_SIZE 1000
I feel it might be better to have it as a parameter rather than fixed at
1000.
> +/*
> + * Analog of NextCopyFrom() but ignore rows with errors while copying.
> + */
> +static bool
> +safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext, Datum
> *values, bool *nulls)
NextCopyFrom() is in copyfromparse.c while safeNextCopyFrom() is in
copyfrom.c.
Since safeNextCopyFrom() is analog of NextCopyFrom() as commented, would
it be natural to put them in the same file?
> 188 + safecstate->errors++;
> 189 + if (safecstate->errors <= 100)
> 190 + ereport(WARNING,
> 191 + (errcode(errdata->sqlerrcode),
> 192 + errmsg("%s", errdata->context)));
It would be better to state in the manual that errors exceeding 100 are
not displayed.
Or, it might be acceptable to output all errors that exceed 100.
> +typedef struct SafeCopyFromState
> +{
> +#define REPLAY_BUFFER_SIZE 1000
> + HeapTuple replay_buffer[REPLAY_BUFFER_SIZE]; /* accumulates
> tuples for replaying it after an error */
> + int saved_tuples; /* # of tuples in
> replay_buffer */
> + int replayed_tuples; /* # of tuples was
> replayed from buffer */
> + int errors; /* total # of errors */
> + bool replay_is_active;
> + bool begin_subtransaction;
> + bool processed_remaining_tuples; /* for case of
> replaying last tuples */
> + bool skip_row;
It would be helpful to add comments about skip_row, etc.
```
$ git apply ../patch/0003-COPY_IGNORE_ERRORS.patch
../patch/0003-COPY_IGNORE_ERRORS.patch:86: indent with spaces.
Datum *values, bool *nulls);
warning: 1 line adds whitespace errors.
```
There was a warning when applying the patch.
```
=# copy test from '/tmp/10000.data' with (ignore_errors);
WARNING: FIND 0 ERRORS
COPY 1003
```
When there were no errors, this WARNING seems not necessary.
--
Regards,
--
Atsushi Torikoshi
NTT DATA CORPORATION
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
@ 2022-08-24 16:54 ` Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2022-08-24 16:54 UTC (permalink / raw)
To: torikoshia <[email protected]>; pgsql-hackers; [email protected]
>
> > + /* Buffer was filled, commit subtransaction and prepare
> to replay */
> > + ReleaseCurrentSubTransaction();
> What is actually being committed by this ReleaseCurrentSubTransaction()?
> It seems to me that just safecstate->replay_buffer is fulfilled before
> this commit.
>
All tuples are collected in replay_buffer, which is created in
''oldcontext'' of CopyFrom() (not context of a subtransaction). That's why
it didn't clean up when you used RollbackAndReleaseCurrentSubTransaction().
Subtransactions are needed for better safety. There is no error when
copying from a file to the replay_buffer, but an error may occur at the
next stage - when adding a tuple to the table. Also there may be other
errors that are not obvious at first glance.
I feel it might be better to have it as a parameter rather than fixed at
> 1000.
>
Yes, I thought about it too. So I created another version with the GUC
parameter - replay_buffer_size. Attached it. But I think users won't need
to change replay_buffer_size.
Also replay_buffer does the same thing as MultiInsert buffer does and
MultiInsert buffer defined by const = 1000.
NextCopyFrom() is in copyfromparse.c while safeNextCopyFrom() is in
> copyfrom.c.
> Since safeNextCopyFrom() is analog of NextCopyFrom() as commented, would
> it be natural to put them in the same file?
>
Sure, corrected it.
> > 188 + safecstate->errors++;
> > 189 + if (safecstate->errors <= 100)
> > 190 + ereport(WARNING,
> > 191 + (errcode(errdata->sqlerrcode),
> > 192 + errmsg("%s", errdata->context)));
>
> It would be better to state in the manual that errors exceeding 100 are
> not displayed.
> Or, it might be acceptable to output all errors that exceed 100.
>
It'll be too complicated to create a new parameter just for showing the
given number of errors. I think 100 is an optimal size.
> > +typedef struct SafeCopyFromState
> > +{
> > +#define REPLAY_BUFFER_SIZE 1000
> > + HeapTuple replay_buffer[REPLAY_BUFFER_SIZE]; /* accumulates
> > tuples for replaying it after an error */
> > + int saved_tuples; /* # of tuples in
> > replay_buffer */
> > + int replayed_tuples; /* # of tuples was
> > replayed from buffer */
> > + int errors; /* total # of errors */
> > + bool replay_is_active;
> > + bool begin_subtransaction;
> > + bool processed_remaining_tuples; /* for case of
> > replaying last tuples */
> > + bool skip_row;
>
> It would be helpful to add comments about skip_row, etc.
>
Corrected it.
> WARNING: FIND 0 ERRORS
> When there were no errors, this WARNING seems not necessary.
>
Corrected it.
Add to this patch processing other errors and constraints and tests for
them.
I had to create another function safeExecConstraints() only for processing
constraints, because ExecConstraints() is after NextCopyFrom() and is not
in PG_TRY. This thing a little bit complicated the code.
Maybe it is a good approach to create a new function SafeCopyFrom() and do
all ''safe copying'' in PG_TRY, but it will almost duplicate the CopyFrom()
code.
Or maybe create a function only for loop for(;;). But we have the same
thing with duplicating code and passing a lot of variables (which are
created at the beginning of CopyFrom()) to this function.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-08-24 16:57 ` Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2022-08-24 16:57 UTC (permalink / raw)
To: torikoshia <[email protected]>; pgsql-hackers; [email protected]
>
Attachments:
[text/x-patch] 0004-COPY_IGNORE_ERRORS.patch (30.6K, ../../CALH1LgvzpORM+EHVXRz4-Dv+_aHvm9m9Hu6eYM4PfppwKgXvFQ@mail.gmail.com/3-0004-COPY_IGNORE_ERRORS.patch)
download | inline diff:
From 09befdad45a6b1ae70d6c5abc90d1c2296e56ee1 Mon Sep 17 00:00:00 2001
From: Damir Belyalov <[email protected]>
Date: Fri, 15 Oct 2021 11:55:18 +0300
Subject: [PATCH] COPY_IGNORE_ERRORS with GUC for replay_buffer size
---
doc/src/sgml/config.sgml | 17 ++
doc/src/sgml/ref/copy.sgml | 19 ++
src/backend/commands/copy.c | 8 +
src/backend/commands/copyfrom.c | 114 +++++++++++-
src/backend/commands/copyfromparse.c | 169 ++++++++++++++++++
src/backend/parser/gram.y | 8 +-
src/backend/utils/misc/guc.c | 11 ++
src/backend/utils/misc/postgresql.conf.sample | 2 +
src/bin/psql/tab-complete.c | 3 +-
src/include/commands/copy.h | 6 +
src/include/commands/copyfrom_internal.h | 19 ++
src/include/parser/kwlist.h | 1 +
src/test/regress/expected/copy2.out | 130 ++++++++++++++
src/test/regress/sql/copy2.sql | 116 ++++++++++++
14 files changed, 617 insertions(+), 6 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 37fd80388c..69373b8d8c 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1961,6 +1961,23 @@ include_dir 'conf.d'
</listitem>
</varlistentry>
+ <varlistentry id="guc-logical-decoding-work-mem" xreflabel="replay_buffer_size">
+ <term><varname>replay_buffer_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>replay_buffer_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the size of buffer for COPY FROM IGNORE_ERRORS option. This buffer
+ is created when subtransaction begins and accumulates tuples until an error
+ occurs. Then it starts replaying stored tuples. the buffer size is the size
+ of the subtransaction. Therefore, on large tables, in order to avoid the
+ error of the maximum number of subtransactions, it should be increased.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-max-stack-depth" xreflabel="max_stack_depth">
<term><varname>max_stack_depth</varname> (<type>integer</type>)
<indexterm>
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 8aae711b3b..7ff6f6dea7 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,24 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drop rows that contain malformed data while copying. These are rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows that result in constraint violations, rows containing columns where
+ the data type's input function raises an error.
+ Outputs warnings about rows with incorrect data (the number of warnings
+ is not more than 100) and the total number of errors.
+ The option is implemented with subtransactions and a buffer created in
+ them, which accumulates tuples until an error occures.
+ The size of buffer is the size of subtransaction block.
+ It is a GUC parameter "replay_buffer_size" and equals 1000 by default.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 3ac731803b..fead1aba46 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -402,6 +402,7 @@ ProcessCopyOptions(ParseState *pstate,
{
bool format_specified = false;
bool freeze_specified = false;
+ bool ignore_errors_specified = false;
bool header_specified = false;
ListCell *option;
@@ -442,6 +443,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index a976008b3d..7e997d15c6 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -73,6 +73,11 @@
/* Trim the list of buffers back down to this number after flushing */
#define MAX_PARTITION_BUFFERS 32
+/*
+ * GUC parameters
+ */
+int replay_buffer_size;
+
/* Stores multi-insert data related to a single relation in CopyFrom. */
typedef struct CopyMultiInsertBuffer
{
@@ -100,12 +105,13 @@ typedef struct CopyMultiInsertInfo
int ti_options; /* table insert options */
} CopyMultiInsertInfo;
-
/* non-export function prototypes */
static char *limit_printout_length(const char *str);
static void ClosePipeFromProgram(CopyFromState cstate);
+static void safeExecConstraints(CopyFromState cstate, ResultRelInfo *resultRelInfo, TupleTableSlot *myslot, EState *estate);
+
/*
* error context callback for COPY FROM
*
@@ -521,6 +527,61 @@ CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
miinfo->bufferedBytes += tuplen;
}
+/*
+ * Ignore constraints if IGNORE_ERRORS is enabled
+ */
+static void
+safeExecConstraints(CopyFromState cstate, ResultRelInfo *resultRelInfo, TupleTableSlot *myslot, EState *estate)
+{
+ SafeCopyFromState *safecstate = cstate->safecstate;
+
+ safecstate->skip_row = false;
+
+ PG_TRY();
+ ExecConstraints(resultRelInfo, myslot, estate);
+ PG_CATCH();
+ {
+ ErrorData *errdata;
+ MemoryContext cxt;
+
+ cxt = MemoryContextSwitchTo(safecstate->oldcontext);
+ errdata = CopyErrorData();
+
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = safecstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore Constraint Violation */
+ case ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION:
+ case ERRCODE_RESTRICT_VIOLATION:
+ case ERRCODE_NOT_NULL_VIOLATION:
+ case ERRCODE_FOREIGN_KEY_VIOLATION:
+ case ERRCODE_UNIQUE_VIOLATION:
+ case ERRCODE_CHECK_VIOLATION:
+ case ERRCODE_EXCLUSION_VIOLATION:
+ safecstate->errors++;
+ if (cstate->safecstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+
+ safecstate->begin_subtransaction = true;
+ safecstate->skip_row = true;
+ break;
+ default:
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(cxt);
+ }
+ PG_END_TRY();
+}
+
/*
* Copy FROM file to relation.
*/
@@ -535,6 +596,7 @@ CopyFrom(CopyFromState cstate)
ExprContext *econtext;
TupleTableSlot *singleslot = NULL;
MemoryContext oldcontext = CurrentMemoryContext;
+ ResourceOwner oldowner = CurrentResourceOwner;
PartitionTupleRouting *proute = NULL;
ErrorContextCallback errcallback;
@@ -819,9 +881,30 @@ CopyFrom(CopyFromState cstate)
errcallback.previous = error_context_stack;
error_context_stack = &errcallback;
+ /* Initialize safeCopyFromState for IGNORE_ERRORS option */
+ if (cstate->opts.ignore_errors)
+ {
+ cstate->safecstate = palloc(sizeof(SafeCopyFromState));
+
+ /* Create replay_buffer in oldcontext */
+ cstate->safecstate->replay_buffer = (HeapTuple *) palloc(replay_buffer_size * sizeof(HeapTuple));
+
+ cstate->safecstate->saved_tuples = 0;
+ cstate->safecstate->replayed_tuples = 0;
+ cstate->safecstate->errors = 0;
+ cstate->safecstate->replay_is_active = false;
+ cstate->safecstate->begin_subtransaction = true;
+ cstate->safecstate->processed_remaining_tuples = false;
+
+ cstate->safecstate->oldowner = oldowner;
+ cstate->safecstate->oldcontext = oldcontext;
+ cstate->safecstate->insertMethod = insertMethod;
+ }
+
for (;;)
{
TupleTableSlot *myslot;
+ bool valid_row;
bool skip_tuple;
CHECK_FOR_INTERRUPTS();
@@ -855,8 +938,21 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ /*
+ * NextCopyFrom() directly store the values/nulls array in the slot.
+ * safeNextCopyFrom() ignores rows with errors if IGNORE_ERRORS is enabled.
+ */
+ if (!cstate->safecstate)
+ valid_row = NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+ else
+ {
+ valid_row = safeNextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+
+ if (cstate->safecstate->skip_row)
+ continue;
+ }
+
+ if (!valid_row)
break;
ExecStoreVirtualTuple(myslot);
@@ -1035,7 +1131,17 @@ CopyFrom(CopyFromState cstate)
*/
if (resultRelInfo->ri_FdwRoutine == NULL &&
resultRelInfo->ri_RelationDesc->rd_att->constr)
- ExecConstraints(resultRelInfo, myslot, estate);
+ {
+ if (cstate->opts.ignore_errors)
+ {
+ safeExecConstraints(cstate, resultRelInfo, myslot, estate);
+
+ if (cstate->safecstate->skip_row)
+ continue;
+ }
+ else
+ ExecConstraints(resultRelInfo, myslot, estate);
+ }
/*
* Also check the tuple against the partition constraint, if
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index 57813b3458..1aae27d80d 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -1026,6 +1026,175 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
return true;
}
+/*
+ * Analog of NextCopyFrom() but skips rows with errors while copying.
+ */
+bool
+safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
+{
+ SafeCopyFromState *safecstate = cstate->safecstate;
+ bool valid_row = true;
+
+ safecstate->skip_row = false;
+
+ PG_TRY();
+ {
+ if (!safecstate->replay_is_active)
+ {
+ if (safecstate->begin_subtransaction)
+ {
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = safecstate->oldowner;
+
+ safecstate->begin_subtransaction = false;
+ }
+
+ if (safecstate->saved_tuples < replay_buffer_size)
+ {
+ valid_row = NextCopyFrom(cstate, econtext, values, nulls);
+ if (valid_row)
+ {
+ /* Fill replay_buffer in CopyFrom() oldcontext */
+ MemoryContext cxt = MemoryContextSwitchTo(safecstate->oldcontext);
+
+ safecstate->replay_buffer[safecstate->saved_tuples++] = heap_form_tuple(RelationGetDescr(cstate->rel), values, nulls);
+ MemoryContextSwitchTo(cxt);
+
+ safecstate->skip_row = true;
+ }
+ else if (!safecstate->processed_remaining_tuples)
+ {
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = safecstate->oldowner;
+
+ if (safecstate->replayed_tuples < safecstate->saved_tuples)
+ {
+ /* Prepare to replay remaining tuples if they exist */
+ safecstate->replay_is_active = true;
+ safecstate->processed_remaining_tuples = true;
+ safecstate->skip_row = true;
+ return true;
+ }
+ }
+ }
+ else
+ {
+ /* Buffer was filled, commit subtransaction and prepare to replay */
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = safecstate->oldowner;
+
+ safecstate->replay_is_active = true;
+ safecstate->begin_subtransaction = true;
+ safecstate->skip_row = true;
+ }
+ }
+ else
+ {
+ if (safecstate->replayed_tuples < safecstate->saved_tuples)
+ /* Replaying tuple */
+ heap_deform_tuple(safecstate->replay_buffer[safecstate->replayed_tuples++], RelationGetDescr(cstate->rel), values, nulls);
+ else
+ {
+ /* Clean up replay_buffer */
+ MemSet(safecstate->replay_buffer, 0, replay_buffer_size * sizeof(HeapTuple));
+ safecstate->saved_tuples = safecstate->replayed_tuples = 0;
+
+ safecstate->replay_is_active = false;
+ safecstate->skip_row = true;
+ }
+ }
+ }
+ PG_CATCH();
+ {
+ ErrorData *errdata;
+ MemoryContext cxt;
+
+ cxt = MemoryContextSwitchTo(safecstate->oldcontext);
+ errdata = CopyErrorData();
+
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = safecstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore malformed data */
+ case ERRCODE_DATA_EXCEPTION:
+ case ERRCODE_ARRAY_ELEMENT_ERROR:
+ case ERRCODE_DATETIME_VALUE_OUT_OF_RANGE:
+ case ERRCODE_INTERVAL_FIELD_OVERFLOW:
+ case ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST:
+ case ERRCODE_INVALID_DATETIME_FORMAT:
+ case ERRCODE_INVALID_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_ESCAPE_SEQUENCE:
+ case ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_PARAMETER_VALUE:
+ case ERRCODE_INVALID_TABLESAMPLE_ARGUMENT:
+ case ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE:
+ case ERRCODE_NULL_VALUE_NOT_ALLOWED:
+ case ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE:
+ case ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED:
+ case ERRCODE_STRING_DATA_LENGTH_MISMATCH:
+ case ERRCODE_STRING_DATA_RIGHT_TRUNCATION:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ case ERRCODE_INVALID_BINARY_REPRESENTATION:
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_UNTRANSLATABLE_CHARACTER:
+ case ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE:
+ case ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION:
+ case ERRCODE_INVALID_JSON_TEXT:
+ case ERRCODE_INVALID_SQL_JSON_SUBSCRIPT:
+ case ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM:
+ case ERRCODE_NO_SQL_JSON_ITEM:
+ case ERRCODE_NON_NUMERIC_SQL_JSON_ITEM:
+ case ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT:
+ case ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED:
+ case ERRCODE_SQL_JSON_ARRAY_NOT_FOUND:
+ case ERRCODE_SQL_JSON_MEMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_NUMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_OBJECT_NOT_FOUND:
+ case ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS:
+ case ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS:
+ case ERRCODE_SQL_JSON_SCALAR_REQUIRED:
+ case ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE:
+ safecstate->errors++;
+ if (safecstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+
+ safecstate->begin_subtransaction = true;
+ safecstate->skip_row = true;
+ break;
+ default:
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(cxt);
+ }
+ PG_END_TRY();
+
+ if (!valid_row)
+ {
+ if (safecstate->errors == 0)
+ ereport(NOTICE,
+ errmsg("FIND %d ERRORS", safecstate->errors));
+ else if (safecstate->errors == 1)
+ ereport(WARNING,
+ errmsg("FIND %d ERROR", safecstate->errors));
+ else
+ ereport(WARNING,
+ errmsg("FIND %d ERRORS", safecstate->errors));
+
+ return false;
+ }
+
+ return true;
+}
+
/*
* Read the next input line and stash it in line_buf.
*
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index df5ceea910..3bb7235b34 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -800,7 +800,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3456,6 +3456,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeInteger(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -17814,6 +17818,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -18393,6 +18398,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 0328029d43..54209a4a3c 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -49,6 +49,7 @@
#include "catalog/pg_parameter_acl.h"
#include "catalog/storage.h"
#include "commands/async.h"
+#include "commands/copy.h"
#include "commands/prepare.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
@@ -2527,6 +2528,16 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
+ {
+ {"replay_buffer_size", PGC_USERSET, RESOURCES_MEM,
+ gettext_noop("Sets the size of replay buffer for COPY FROM IGNORE_ERRORS option"),
+ NULL
+ },
+ &replay_buffer_size,
+ 1000, 1, INT_MAX,
+ NULL, NULL, NULL
+ },
+
/*
* We use the hopefully-safely-small value of 100kB as the compiled-in
* default for max_stack_depth. InitializeGUCOptions will increase it if
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index b4bc06e5f5..f4e777a0a3 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -155,6 +155,8 @@
# mmap
# (change requires restart)
#min_dynamic_shared_memory = 0MB # (change requires restart)
+#replay_buffer_size = 1000 # min 1
+ # (change requires restart)
# - Disk -
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index e572f585ef..feaf18b043 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2742,7 +2742,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index cb0096aeb6..fc9f559efe 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -19,6 +19,9 @@
#include "parser/parse_node.h"
#include "tcop/dest.h"
+/* User-settable GUC parameters */
+extern PGDLLIMPORT int replay_buffer_size;
+
/*
* Represents whether a header line should be present, and whether it must
* match the actual names (which implies "true").
@@ -42,6 +45,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
@@ -78,6 +82,8 @@ extern CopyFromState BeginCopyFrom(ParseState *pstate, Relation rel, Node *where
extern void EndCopyFrom(CopyFromState cstate);
extern bool NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
Datum *values, bool *nulls);
+extern bool safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext,
+ Datum *values, bool *nulls);
extern bool NextCopyFromRawFields(CopyFromState cstate,
char ***fields, int *nfields);
extern void CopyFromErrorCallback(void *arg);
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index 3df1c5a97c..4227a7babd 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -16,6 +16,7 @@
#include "commands/copy.h"
#include "commands/trigger.h"
+#include "utils/resowner.h"
/*
* Represents the different source cases we need to worry about at
@@ -49,6 +50,23 @@ typedef enum CopyInsertMethod
CIM_MULTI_CONDITIONAL /* use table_multi_insert only if valid */
} CopyInsertMethod;
+ /* Struct that holding fields for COPY FROM IGNORE_ERRORS option. */
+typedef struct SafeCopyFromState
+{
+ HeapTuple *replay_buffer; /* accumulates tuples for replaying them after an error */
+ int saved_tuples; /* # of tuples in replay_buffer */
+ int replayed_tuples; /* # of tuples was replayed from buffer */
+ int errors; /* total # of errors */
+ bool replay_is_active; /* become active after an error */
+ bool begin_subtransaction; /* if it's true, we can start subtransaction */
+ bool processed_remaining_tuples; /* for case of replaying last tuples */
+ bool skip_row; /* if it's true, we should skip this row */
+
+ MemoryContext oldcontext; /* create repay_buffer in CopyFrom() context */
+ ResourceOwner oldowner; /* CopyFrom() resource owner */
+ CopyInsertMethod insertMethod;
+} SafeCopyFromState;
+
/*
* This struct contains all the state variables used throughout a COPY FROM
* operation.
@@ -71,6 +89,7 @@ typedef struct CopyFromStateData
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
+ SafeCopyFromState *safecstate; /* struct for ignore_errors option */
CopyFormatOptions opts;
bool *convert_select_flags; /* per-column CSV/TEXT CS flags */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index ae35f03251..2af11bd359 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -201,6 +201,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..093c7958be 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,136 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int check (n < 8), m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column n: "5 {5} 5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: COPY check_ign_err, line 8, column n: "8 {8} 8"
+WARNING: FIND 7 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[]);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column n: "5 {5} 5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: COPY check_ign_err, line 8, column n: "8 {8} 8"
+WARNING: FIND 7 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO check_ign_err VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err_view, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 {3}"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column n: "5 {5} 5555555555"
+WARNING: COPY check_ign_err_view, line 6, column n: ""
+WARNING: COPY check_ign_err_view, line 7, column m: "{a, 7}"
+WARNING: COPY check_ign_err_view, line 8, column n: "8 {8} 8"
+WARNING: FIND 7 ERRORS
+SELECT * FROM check_ign_err_view;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* find values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column n: "5 {5} 5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: COPY check_ign_err, line 8, column n: "8 {8} 8"
+WARNING: FIND 7 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int check (n < 8), m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (8);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column n: "5 {5} 5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: COPY check_ign_err, line 8, column n: "8 {8} 8"
+WARNING: FIND 7 ERRORS
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..c91122aa1e 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,122 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int check (n < 8), m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[]);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO check_ign_err VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err_view;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* find values equal 1 */
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int check (n < 8), m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (8);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
--
2.25.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-08-29 13:02 ` torikoshia <[email protected]>
2022-09-21 12:11 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: torikoshia @ 2022-08-29 13:02 UTC (permalink / raw)
To: Damir Belyalov <[email protected]>; +Cc: pgsql-hackers; [email protected]
On 2022-08-25 01:54, Damir Belyalov wrote:
>>> + /* Buffer was filled, commit subtransaction and
>> prepare to replay */
>>> + ReleaseCurrentSubTransaction();
>> What is actually being committed by this
>> ReleaseCurrentSubTransaction()?
>> It seems to me that just safecstate->replay_buffer is fulfilled
>> before
>> this commit.
>
> All tuples are collected in replay_buffer, which is created in
> ''oldcontext'' of CopyFrom() (not context of a subtransaction). That's
> why it didn't clean up when you used
> RollbackAndReleaseCurrentSubTransaction().
> Subtransactions are needed for better safety. There is no error when
> copying from a file to the replay_buffer, but an error may occur at
> the next stage - when adding a tuple to the table. Also there may be
> other errors that are not obvious at first glance.
Thanks for the explanation and updating patch.
I now understand that the data being COPYed are not the target of
COMMIT.
Although in past discussions[1] it seems the data to be COPYed were also
subject to COMMIT, but I understand this patch has adopted another
design.
350 + /* Buffer was filled, commit subtransaction and
prepare to replay */
351 + ReleaseCurrentSubTransaction();
352 + CurrentResourceOwner = safecstate->oldowner;
353 +
354 + safecstate->replay_is_active = true;
BTW in v4 patch, data are loaded into the buffer one by one, and when
the buffer fills up, the data in the buffer are 'replayed' also one by
one, right?
Wouldn't this have more overhead than a normal COPY?
As a test, I COPYed slightly larger data with and without ignore_errors
option.
There might be other reasons, but I found a performance difference.
```
=# copy test from '/tmp/10000000.data' ;
COPY 10000000
Time: 6001.325 ms (00:06.001)
=# copy test from '/tmp/10000000.data' with (ignore_errors);
NOTICE: FIND 0 ERRORS
COPY 10000000
Time: 7711.555 ms (00:07.712)
```
>> I feel it might be better to have it as a parameter rather than
>> fixed at
>> 1000.
>
> Yes, I thought about it too. So I created another version with the GUC
> parameter - replay_buffer_size. Attached it. But I think users won't
> need to change replay_buffer_size.
> Also replay_buffer does the same thing as MultiInsert buffer does and
> MultiInsert buffer defined by const = 1000.
Yeah, when the data being COPYed are not the target of COMMIT, I also
think users won't neet to change it.
>
>> NextCopyFrom() is in copyfromparse.c while safeNextCopyFrom() is in
>> copyfrom.c.
>> Since safeNextCopyFrom() is analog of NextCopyFrom() as commented,
>> would
>> it be natural to put them in the same file?
>
> Sure, corrected it.
Thanks.
>
>>> 188 + safecstate->errors++;
>>> 189 + if (safecstate->errors <= 100)
>>> 190 + ereport(WARNING,
>>> 191 + (errcode(errdata->sqlerrcode),
>>> 192 + errmsg("%s", errdata->context)));
>>
>> It would be better to state in the manual that errors exceeding 100
>> are
>> not displayed.
>> Or, it might be acceptable to output all errors that exceed 100.
>
> It'll be too complicated to create a new parameter just for showing
> the given number of errors. I think 100 is an optimal size.
Yeah, I may have misled you, but I also don't think this needs a new
parameter.
I just thought 'either' of the following would be better:
- Put in the documentation that the warnings will not be output for more
than 101 cases.
- Output all the warnings.
>> It would be helpful to add comments about skip_row, etc.
>
> Corrected it.
Thanks.
>
>> WARNING: FIND 0 ERRORS
>> When there were no errors, this WARNING seems not necessary.
>
> Corrected it.
Thanks.
I applied v4 patch and when canceled the COPY, there was a case I found
myself left in a transaction.
Should this situation be prevented from occurring?
```
=# copy test from '/tmp/10000000.data' with (ignore_errors );
^CCancel request sent
ERROR: canceling statement due to user request
=# truncate test;
ERROR: current transaction is aborted, commands ignored until end of
transaction block
```
[1]
https://www.postgresql.org/message-id/1197677930.1536.18.camel%40dell.linuxdev.us.dell.com
--
Regards,
--
Atsushi Torikoshi
NTT DATA CORPORATION
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
@ 2022-09-21 12:11 ` Damir Belyalov <[email protected]>
2022-09-26 13:04 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2022-09-21 12:11 UTC (permalink / raw)
To: torikoshia <[email protected]>; pgsql-hackers; [email protected]
Thank you for reviewing.
In the previous patch there was an error when processing constraints. The
patch was fixed, but the code grew up and became more complicated
(0005-COPY_IGNORE_ERRORS). I also simplified the logic of
safeNextCopyFrom().
You asked why we need subtransactions, so the answer is in this patch. When
processing a row that does not satisfy constraints or INSTEAD OF triggers,
it is necessary to rollback the subtransaction and return the table to its
original state.
Cause of complexity, I had to abandon the constraints, triggers processing
in and handle only errors that occur when reading the file. Attaching
simplified patch (0006-COPY_IGNORE_ERRORS).
Checked out these patches on all COPY regress tests and it worked correctly.
> BTW in v4 patch, data are loaded into the buffer one by one, and when
> the buffer fills up, the data in the buffer are 'replayed' also one by
> one, right?
> Wouldn't this have more overhead than a normal COPY?
>
The data is loaded into the buffer one by one, but in the "replay mode"
ignore_errors works as standard COPY. Tuples add to the slot and depending
on the type of the slot (CIM_SINGLE or CIM_MULTI) tuples are replayed in
the corresponding case.
For the 0006 patch you can imagine that we divide the loop for(;;) in 2
parts. The first part is adding tuples to the buffer and the second part is
inserting tuples to the table. These parts don't intersect with each other
and are completed sequentially.
The main idea of replay_buffer is that it is needed for the CIM_SINGLE
case. You can implement the CIM_SINGLE case and see that tuples before an
error occurring don't add to the table. Logic of the 0005 patch is similar
but with some differences.
As a test, I COPYed slightly larger data with and without ignore_errors
> option.
> There might be other reasons, but I found a performance difference.
Tried to reduce performance difference with cleaning up replay_buffer with
resetting the new context for replay_buffer - replay_cxt.
```
Before:
Without ignore_errors:
COPY 10000000
Time: 15538,579 ms (00:15,539)
With ignore_errors:
COPY 10000000
Time: 21289,121 ms (00:21,289)
After:
Without ignore_errors:
COPY 10000000
Time: 15318,922 ms (00:15,319)
With ignore_errors:
COPY 10000000
Time: 19868,175 ms (00:19,868)
```
- Put in the documentation that the warnings will not be output for more
> than 101 cases.
>
Yeah, I point it out in the doc.
> I applied v4 patch and when canceled the COPY, there was a case I found
> myself left in a transaction.
> Should this situation be prevented from occurring?
>
> ```
> =# copy test from '/tmp/10000000.data' with (ignore_errors );
>
> ^CCancel request sent
> ERROR: canceling statement due to user request
>
> =# truncate test;
> ERROR: current transaction is aborted, commands ignored until end of
> transaction block
> ```
>
Tried to implement your error and could not. The result was the same as
COPY FROM implements.
Attachments:
[text/x-patch] 0005-COPY_IGNORE_ERRORS.patch (27.1K, ../../CALH1Lgsr7Asz6r6jnRta7DVEjKwyz=b3XJhyCMoYv8Yy9y4cXg@mail.gmail.com/3-0005-COPY_IGNORE_ERRORS.patch)
download | inline diff:
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index c25b52d0cb..c99adabcc9 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,20 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drops rows that contain malformed data while copying. These are rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows that result in constraint violations, rows containing columns where
+ the data type's input function raises an error.
+ Outputs warnings about rows with incorrect data (the number of warnings
+ is not more than 100) and the total number of errors.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 49924e476a..f41b25f26a 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -406,6 +406,7 @@ ProcessCopyOptions(ParseState *pstate,
bool is_from,
List *options)
{
+ bool ignore_errors_specified = false;
bool format_specified = false;
bool freeze_specified = false;
bool header_specified = false;
@@ -448,6 +449,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index e8bb168aea..6474d47d29 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -106,6 +106,12 @@ static char *limit_printout_length(const char *str);
static void ClosePipeFromProgram(CopyFromState cstate);
+static bool safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext,
+ Datum *values, bool *nulls);
+static bool safeExecConstraints(CopyFromState cstate, ResultRelInfo *resultRelInfo, TupleTableSlot *myslot, EState *estate);
+
+static void addToReplayBuffer(CopyFromState cstate, TupleTableSlot *myslot);
+
/*
* error context callback for COPY FROM
*
@@ -521,6 +527,254 @@ CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
miinfo->bufferedBytes += tuplen;
}
+/*
+ * Analog of NextCopyFrom() but ignores rows with errors while copying.
+ */
+bool
+safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
+{
+ SafeCopyFromState *sfcstate = cstate->sfcstate;
+
+ sfcstate->tuple_is_valid = false;
+
+ PG_TRY();
+ {
+ if (sfcstate->begin_subxact)
+ {
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->begin_subxact = false;
+ }
+
+ if (!sfcstate->replay_is_active)
+ {
+ if (sfcstate->saved_tuples < REPLAY_BUFFER_SIZE)
+ {
+ MemoryContext cxt = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+ bool valid_row = NextCopyFrom(cstate, econtext, values, nulls);
+
+ CurrentMemoryContext = cxt;
+
+ sfcstate->tuple_is_valid = true;
+
+ if (!valid_row && sfcstate->replayed_tuples < sfcstate->saved_tuples)
+ {
+ /* Prepare for replaying remaining tuples if they exist */
+ sfcstate->replay_is_active = true;
+
+ /* If there are insteadof triggers we should rollback subtransaction */
+ if (sfcstate->has_instead_insert_row_trig)
+ {
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->begin_subxact = true;
+ }
+ }
+ else if (!valid_row)
+ {
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ if (sfcstate->errors == 0)
+ ereport(NOTICE,
+ errmsg("%d errors", sfcstate->errors));
+ else if (sfcstate->errors == 1)
+ ereport(WARNING,
+ errmsg("%d error", sfcstate->errors));
+ else
+ ereport(WARNING,
+ errmsg("%d errors", sfcstate->errors));
+
+ return false;
+ }
+ }
+ else
+ {
+ /* Buffer was filled, prepare for replaying */
+ sfcstate->replay_is_active = true;
+
+ /* If there are insteadof triggers we should rollback subtransaction */
+ if (sfcstate->has_instead_insert_row_trig)
+ {
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->begin_subxact = true;
+ }
+ }
+ }
+
+ if (sfcstate->replay_is_active)
+ {
+ if (sfcstate->replayed_tuples < sfcstate->saved_tuples)
+ {
+ /* Replaying the tuple */
+ MemoryContext cxt = MemoryContextSwitchTo(sfcstate->replay_cxt);
+
+ heap_deform_tuple(sfcstate->replay_buffer[sfcstate->replayed_tuples++], RelationGetDescr(cstate->rel), values, nulls);
+ MemoryContextSwitchTo(cxt);
+
+ sfcstate->tuple_is_valid = true;
+ }
+ else
+ {
+ /* Clean up replay_buffer */
+ MemoryContextReset(sfcstate->replay_cxt);
+ sfcstate->saved_tuples = sfcstate->replayed_tuples = 0;
+
+ cstate->sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->begin_subxact = true;
+ sfcstate->replay_is_active = false;
+ }
+ }
+ }
+ PG_CATCH();
+ {
+ MemoryContext ecxt = MemoryContextSwitchTo(sfcstate->oldcontext);
+ ErrorData *errdata = CopyErrorData();
+
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore data exceptions */
+ case ERRCODE_CHARACTER_NOT_IN_REPERTOIRE:
+ case ERRCODE_DATA_EXCEPTION:
+ case ERRCODE_ARRAY_ELEMENT_ERROR:
+ case ERRCODE_DATETIME_VALUE_OUT_OF_RANGE:
+ case ERRCODE_INTERVAL_FIELD_OVERFLOW:
+ case ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST:
+ case ERRCODE_INVALID_DATETIME_FORMAT:
+ case ERRCODE_INVALID_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_ESCAPE_SEQUENCE:
+ case ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_PARAMETER_VALUE:
+ case ERRCODE_INVALID_TABLESAMPLE_ARGUMENT:
+ case ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE:
+ case ERRCODE_NULL_VALUE_NOT_ALLOWED:
+ case ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE:
+ case ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED:
+ case ERRCODE_STRING_DATA_LENGTH_MISMATCH:
+ case ERRCODE_STRING_DATA_RIGHT_TRUNCATION:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ case ERRCODE_INVALID_BINARY_REPRESENTATION:
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_UNTRANSLATABLE_CHARACTER:
+ case ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE:
+ case ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION:
+ case ERRCODE_INVALID_JSON_TEXT:
+ case ERRCODE_INVALID_SQL_JSON_SUBSCRIPT:
+ case ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM:
+ case ERRCODE_NO_SQL_JSON_ITEM:
+ case ERRCODE_NON_NUMERIC_SQL_JSON_ITEM:
+ case ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT:
+ case ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED:
+ case ERRCODE_SQL_JSON_ARRAY_NOT_FOUND:
+ case ERRCODE_SQL_JSON_MEMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_NUMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_OBJECT_NOT_FOUND:
+ case ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS:
+ case ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS:
+ case ERRCODE_SQL_JSON_SCALAR_REQUIRED:
+ case ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE:
+ sfcstate->errors++;
+ if (sfcstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+
+ sfcstate->begin_subxact = true;
+
+ break;
+ default:
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(ecxt);
+ }
+ PG_END_TRY();
+
+ return true;
+}
+
+/*
+ * Analog of ExecConstraints(), but ignores rows in constraint violations.
+ */
+bool
+safeExecConstraints(CopyFromState cstate, ResultRelInfo *resultRelInfo, TupleTableSlot *myslot, EState *estate)
+{
+ SafeCopyFromState *sfcstate = cstate->sfcstate;
+
+ PG_TRY();
+ ExecConstraints(resultRelInfo, myslot, estate);
+ PG_CATCH();
+ {
+ MemoryContext ecxt = MemoryContextSwitchTo(sfcstate->oldcontext);
+ ErrorData *errdata = CopyErrorData();
+
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore constraint violations */
+ case ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION:
+ case ERRCODE_RESTRICT_VIOLATION:
+ case ERRCODE_NOT_NULL_VIOLATION:
+ case ERRCODE_FOREIGN_KEY_VIOLATION:
+ case ERRCODE_UNIQUE_VIOLATION:
+ case ERRCODE_CHECK_VIOLATION:
+ case ERRCODE_EXCLUSION_VIOLATION:
+ sfcstate->errors++;
+ if (sfcstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s %s", errdata->message, errdata->detail)));
+
+ sfcstate->begin_subxact = true;
+ sfcstate->tuple_is_valid = false;
+
+ break;
+ default:
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(ecxt);
+ }
+ PG_END_TRY();
+
+ if (!sfcstate->tuple_is_valid)
+ return false;
+
+ return true;
+}
+
+void
+addToReplayBuffer(CopyFromState cstate, TupleTableSlot *myslot)
+{
+ MemoryContext cxt = MemoryContextSwitchTo(cstate->sfcstate->replay_cxt);
+ HeapTuple saved_tuple = heap_form_tuple(RelationGetDescr(cstate->rel), myslot->tts_values, myslot->tts_isnull);
+
+ cstate->sfcstate->replay_buffer[cstate->sfcstate->saved_tuples++] = saved_tuple;
+ MemoryContextSwitchTo(cxt);
+}
+
/*
* Copy FROM file to relation.
*/
@@ -535,6 +789,7 @@ CopyFrom(CopyFromState cstate)
ExprContext *econtext;
TupleTableSlot *singleslot = NULL;
MemoryContext oldcontext = CurrentMemoryContext;
+ ResourceOwner oldowner = CurrentResourceOwner;
PartitionTupleRouting *proute = NULL;
ErrorContextCallback errcallback;
@@ -819,6 +1074,27 @@ CopyFrom(CopyFromState cstate)
errcallback.previous = error_context_stack;
error_context_stack = &errcallback;
+ /* Initialize safeCopyFromState for IGNORE_ERRORS option */
+ if (cstate->opts.ignore_errors)
+ {
+ cstate->sfcstate = palloc(sizeof(SafeCopyFromState));
+
+ cstate->sfcstate->replay_cxt = AllocSetContextCreate(oldcontext,
+ "Replay context",
+ ALLOCSET_DEFAULT_SIZES);
+ cstate->sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ cstate->sfcstate->saved_tuples = 0;
+ cstate->sfcstate->replayed_tuples = 0;
+ cstate->sfcstate->errors = 0;
+ cstate->sfcstate->replay_is_active = false;
+ cstate->sfcstate->begin_subxact = true;
+ cstate->sfcstate->oldowner = oldowner;
+ cstate->sfcstate->oldcontext = oldcontext;
+ if (has_instead_insert_row_trig)
+ cstate->sfcstate->has_instead_insert_row_trig = true;
+ }
+
for (;;)
{
TupleTableSlot *myslot;
@@ -855,19 +1131,25 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
- break;
+ if (cstate->sfcstate)
+ {
+ /* If option IGNORE_ERRORS is enabled, COPY skips rows with errors */
+ if (!safeNextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
+ if (!cstate->sfcstate->tuple_is_valid)
+ continue;
+ }
+ else
+ {
+ /* Directly store the values/nulls array in the slot */
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
+ }
ExecStoreVirtualTuple(myslot);
- /*
- * Constraints and where clause might reference the tableoid column,
- * so (re-)initialize tts_tableOid before evaluating them.
- */
myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc);
- /* Triggers and stuff need to be invoked in query context. */
MemoryContextSwitchTo(oldcontext);
if (cstate->whereClause)
@@ -1020,6 +1302,13 @@ CopyFrom(CopyFromState cstate)
if (has_instead_insert_row_trig)
{
ExecIRInsertTriggers(estate, resultRelInfo, myslot);
+
+ /* Add tuple to replay_buffer if IGNORE_ERRORS is enabled */
+ if (cstate->sfcstate && !cstate->sfcstate->replay_is_active)
+ {
+ addToReplayBuffer(cstate, myslot);
+ continue;
+ }
}
else
{
@@ -1035,7 +1324,15 @@ CopyFrom(CopyFromState cstate)
*/
if (resultRelInfo->ri_FdwRoutine == NULL &&
resultRelInfo->ri_RelationDesc->rd_att->constr)
- ExecConstraints(resultRelInfo, myslot, estate);
+ {
+ if (cstate->sfcstate)
+ {
+ if (!safeExecConstraints(cstate, resultRelInfo, myslot, estate))
+ continue;
+ }
+ else
+ ExecConstraints(resultRelInfo, myslot, estate);
+ }
/*
* Also check the tuple against the partition constraint, if
@@ -1047,6 +1344,13 @@ CopyFrom(CopyFromState cstate)
(proute == NULL || has_before_insert_row_trig))
ExecPartitionCheck(resultRelInfo, myslot, estate, true);
+ /* Add tuple to replay_buffer if IGNORE_ERRORS is enabled */
+ if (cstate->sfcstate && !cstate->sfcstate->replay_is_active)
+ {
+ addToReplayBuffer(cstate, myslot);
+ continue;
+ }
+
/* Store the slot in the multi-insert buffer, when enabled. */
if (insertMethod == CIM_MULTI || leafpart_use_multi_insert)
{
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b5ab9d9c9a..b49954c0aa 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -808,7 +808,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3477,6 +3477,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeBoolean(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -17778,6 +17782,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -18357,6 +18362,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 62a39779b9..fe590ff7a8 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2748,7 +2748,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index cb0096aeb6..2b696f99bc 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -42,6 +42,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index e37c6032ae..5615fa55ef 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -16,6 +16,7 @@
#include "commands/copy.h"
#include "commands/trigger.h"
+#include "utils/resowner.h"
/*
* Represents the different source cases we need to worry about at
@@ -49,6 +50,24 @@ typedef enum CopyInsertMethod
CIM_MULTI_CONDITIONAL /* use table_multi_insert only if valid */
} CopyInsertMethod;
+/* Struct that holding fields for ignore_errors option. */
+typedef struct SafeCopyFromState
+{
+#define REPLAY_BUFFER_SIZE 10
+ HeapTuple *replay_buffer; /* accumulates tuples for replaying it after an error */
+ int saved_tuples; /* # of tuples in replay_buffer */
+ int replayed_tuples; /* # of tuples was replayed from buffer */
+ int errors; /* total # of errors */
+ bool replay_is_active; /* if true we replay tuples from buffer */
+ bool begin_subxact; /* if true we can begin subtransaction */
+ bool tuple_is_valid;
+ bool has_instead_insert_row_trig;
+
+ MemoryContext replay_cxt;
+ MemoryContext oldcontext;
+ ResourceOwner oldowner;
+} SafeCopyFromState;
+
/*
* This struct contains all the state variables used throughout a COPY FROM
* operation.
@@ -71,6 +90,7 @@ typedef struct CopyFromStateData
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
+ SafeCopyFromState *sfcstate; /* struct for ignore_errors option */
CopyFormatOptions opts;
bool *convert_select_flags; /* per-column CSV/TEXT CS flags */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index ae35f03251..2af11bd359 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -201,6 +201,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..d74575fd40 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,134 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int check (n != 6), m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: new row for relation "check_ign_err" violates check constraint "check_ign_err_n_check" Failing row contains (6, {6}, 6).
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+ FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: new row for relation "check_ign_err" violates check constraint "check_ign_err_n_check" Failing row contains (6, {6}, 6).
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+ FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err_view, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 {3}"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err_view, line 7, column m: "{a, 7}"
+WARNING: 5 errors
+SELECT * FROM trig_test;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 6 | {6} | 6
+ 8 | {8} | 8
+(3 rows)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case is in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 5 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int check (n != 6), m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+ FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: new row for relation "check_ign_err_part2" violates check constraint "check_ign_err_n_check" Failing row contains (6, {6}, 6).
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..8d29ceba26 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,122 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int check (n != 6), m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+6 {6} 6
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+ FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+6 {6} 6
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+ FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+6 {6} 6
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM trig_test;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case is in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+6 {6} 6
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int check (n != 6), m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+ FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+6 {6} 6
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
[text/x-patch] 0006-COPY_IGNORE_ERRORS.patch (23.7K, ../../CALH1Lgsr7Asz6r6jnRta7DVEjKwyz=b3XJhyCMoYv8Yy9y4cXg@mail.gmail.com/4-0006-COPY_IGNORE_ERRORS.patch)
download | inline diff:
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index c25b52d0cb..22c992e6f6 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,19 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drops rows that contain malformed data while copying. These are rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows containing columns where the data type's input function raises an error.
+ Outputs warnings about rows with incorrect data (the number of warnings
+ is not more than 100) and the total number of errors.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 49924e476a..f41b25f26a 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -406,6 +406,7 @@ ProcessCopyOptions(ParseState *pstate,
bool is_from,
List *options)
{
+ bool ignore_errors_specified = false;
bool format_specified = false;
bool freeze_specified = false;
bool header_specified = false;
@@ -448,6 +449,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index e8bb168aea..39f1dca084 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -535,6 +535,7 @@ CopyFrom(CopyFromState cstate)
ExprContext *econtext;
TupleTableSlot *singleslot = NULL;
MemoryContext oldcontext = CurrentMemoryContext;
+ ResourceOwner oldowner = CurrentResourceOwner;
PartitionTupleRouting *proute = NULL;
ErrorContextCallback errcallback;
@@ -819,6 +820,26 @@ CopyFrom(CopyFromState cstate)
errcallback.previous = error_context_stack;
error_context_stack = &errcallback;
+ /* Initialize safeCopyFromState for IGNORE_ERRORS option*/
+ if (cstate->opts.ignore_errors)
+ {
+ cstate->sfcstate = palloc(sizeof(SafeCopyFromState));
+
+ cstate->sfcstate->replay_cxt = AllocSetContextCreate(oldcontext,
+ "Replay_context",
+ ALLOCSET_DEFAULT_SIZES);
+ cstate->sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ cstate->sfcstate->saved_tuples = 0;
+ cstate->sfcstate->replayed_tuples = 0;
+ cstate->sfcstate->errors = 0;
+ cstate->sfcstate->replay_is_active = false;
+ cstate->sfcstate->begin_subxact = true;
+
+ cstate->sfcstate->oldowner = oldowner;
+ cstate->sfcstate->oldcontext = oldcontext;
+ }
+
for (;;)
{
TupleTableSlot *myslot;
@@ -855,9 +876,18 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
- break;
+ if (cstate->sfcstate)
+ {
+ /* If option IGNORE_ERRORS is enabled, COPY skips rows with errors */
+ if (!safeNextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
+ if (!cstate->sfcstate->replay_is_active)
+ continue;
+ }
+ else
+ /* Directly store the values/nulls array in the slot */
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
ExecStoreVirtualTuple(myslot);
@@ -1035,7 +1065,21 @@ CopyFrom(CopyFromState cstate)
*/
if (resultRelInfo->ri_FdwRoutine == NULL &&
resultRelInfo->ri_RelationDesc->rd_att->constr)
- ExecConstraints(resultRelInfo, myslot, estate);
+ {
+ if (cstate->opts.ignore_errors)
+ {
+ PG_TRY();
+ ExecConstraints(resultRelInfo, myslot, estate);
+ PG_CATCH();
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = cstate->sfcstate->oldowner;
+
+ PG_RE_THROW();
+ PG_END_TRY();
+ }
+ else
+ ExecConstraints(resultRelInfo, myslot, estate);
+ }
/*
* Also check the tuple against the partition constraint, if
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index 7cf3e865cf..6b92e781e3 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -839,6 +839,169 @@ NextCopyFromRawFields(CopyFromState cstate, char ***fields, int *nfields)
return true;
}
+/*
+ * Analog of NextCopyFrom() but ignores rows with errors while copying.
+ */
+bool
+safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext, Datum *values, bool *nulls)
+{
+ SafeCopyFromState *sfcstate = cstate->sfcstate;
+
+ PG_TRY();
+ {
+ if (sfcstate->begin_subxact)
+ {
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->begin_subxact = false;
+ }
+
+ if (!sfcstate->replay_is_active)
+ {
+ if (sfcstate->saved_tuples < REPLAY_BUFFER_SIZE)
+ {
+ MemoryContext cxt = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+ bool valid_row = NextCopyFrom(cstate, econtext, values, nulls);
+
+ CurrentMemoryContext = cxt;
+
+ if (valid_row)
+ {
+ /* Filling replay_buffer in Replay_context */
+ MemoryContext cxt = MemoryContextSwitchTo(sfcstate->replay_cxt);
+ HeapTuple saved_tuple = heap_form_tuple(RelationGetDescr(cstate->rel), values, nulls);
+
+ sfcstate->replay_buffer[sfcstate->saved_tuples++] = saved_tuple;
+ MemoryContextSwitchTo(cxt);
+ }
+ else if (sfcstate->replayed_tuples < sfcstate->saved_tuples)
+ /* Prepare for replaying remaining tuples if they exist */
+ sfcstate->replay_is_active = true;
+ else
+ {
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ if (sfcstate->errors == 0)
+ ereport(NOTICE,
+ errmsg("%d errors", sfcstate->errors));
+ else if (sfcstate->errors == 1)
+ ereport(WARNING,
+ errmsg("%d error", sfcstate->errors));
+ else
+ ereport(WARNING,
+ errmsg("%d errors", sfcstate->errors));
+
+ return false;
+ }
+ }
+ else
+ /* Buffer was filled, prepare for replaying */
+ sfcstate->replay_is_active = true;
+ }
+
+ if (sfcstate->replay_is_active)
+ {
+ if (sfcstate->replayed_tuples < sfcstate->saved_tuples)
+ {
+ /* Replaying the tuple */
+ MemoryContext cxt = MemoryContextSwitchTo(sfcstate->replay_cxt);
+
+ heap_deform_tuple(sfcstate->replay_buffer[sfcstate->replayed_tuples++], RelationGetDescr(cstate->rel), values, nulls);
+ MemoryContextSwitchTo(cxt);
+ }
+ else
+ {
+ /* Clean up replay_buffer */
+ MemoryContextReset(sfcstate->replay_cxt);
+ sfcstate->saved_tuples = sfcstate->replayed_tuples = 0;
+
+ cstate->sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->begin_subxact = true;
+ sfcstate->replay_is_active = false;
+ }
+ }
+ }
+ PG_CATCH();
+ {
+ MemoryContext ecxt = MemoryContextSwitchTo(sfcstate->oldcontext);
+ ErrorData *errdata = CopyErrorData();
+
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore data exceptions */
+ case ERRCODE_CHARACTER_NOT_IN_REPERTOIRE:
+ case ERRCODE_DATA_EXCEPTION:
+ case ERRCODE_ARRAY_ELEMENT_ERROR:
+ case ERRCODE_DATETIME_VALUE_OUT_OF_RANGE:
+ case ERRCODE_INTERVAL_FIELD_OVERFLOW:
+ case ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST:
+ case ERRCODE_INVALID_DATETIME_FORMAT:
+ case ERRCODE_INVALID_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_ESCAPE_SEQUENCE:
+ case ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_PARAMETER_VALUE:
+ case ERRCODE_INVALID_TABLESAMPLE_ARGUMENT:
+ case ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE:
+ case ERRCODE_NULL_VALUE_NOT_ALLOWED:
+ case ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE:
+ case ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED:
+ case ERRCODE_STRING_DATA_LENGTH_MISMATCH:
+ case ERRCODE_STRING_DATA_RIGHT_TRUNCATION:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ case ERRCODE_INVALID_BINARY_REPRESENTATION:
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_UNTRANSLATABLE_CHARACTER:
+ case ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE:
+ case ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION:
+ case ERRCODE_INVALID_JSON_TEXT:
+ case ERRCODE_INVALID_SQL_JSON_SUBSCRIPT:
+ case ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM:
+ case ERRCODE_NO_SQL_JSON_ITEM:
+ case ERRCODE_NON_NUMERIC_SQL_JSON_ITEM:
+ case ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT:
+ case ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED:
+ case ERRCODE_SQL_JSON_ARRAY_NOT_FOUND:
+ case ERRCODE_SQL_JSON_MEMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_NUMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_OBJECT_NOT_FOUND:
+ case ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS:
+ case ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS:
+ case ERRCODE_SQL_JSON_SCALAR_REQUIRED:
+ case ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE:
+ sfcstate->errors++;
+ if (sfcstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+
+ sfcstate->begin_subxact = true;
+
+ break;
+ default:
+ PG_RE_THROW();
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(ecxt);
+ }
+ PG_END_TRY();
+
+ return true;
+}
+
/*
* Read next tuple from file for COPY FROM. Return false if no more tuples.
*
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b5ab9d9c9a..b49954c0aa 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -808,7 +808,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3477,6 +3477,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeBoolean(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -17778,6 +17782,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -18357,6 +18362,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 62a39779b9..fe590ff7a8 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2748,7 +2748,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index cb0096aeb6..006e1024e1 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -42,6 +42,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
@@ -76,6 +77,8 @@ extern CopyFromState BeginCopyFrom(ParseState *pstate, Relation rel, Node *where
const char *filename,
bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options);
extern void EndCopyFrom(CopyFromState cstate);
+extern bool safeNextCopyFrom(CopyFromState cstate, ExprContext *econtext,
+ Datum *values, bool *nulls);
extern bool NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
Datum *values, bool *nulls);
extern bool NextCopyFromRawFields(CopyFromState cstate,
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index e37c6032ae..9100d5f247 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -16,6 +16,7 @@
#include "commands/copy.h"
#include "commands/trigger.h"
+#include "utils/resowner.h"
/*
* Represents the different source cases we need to worry about at
@@ -49,6 +50,24 @@ typedef enum CopyInsertMethod
CIM_MULTI_CONDITIONAL /* use table_multi_insert only if valid */
} CopyInsertMethod;
+/*
+ * Struct that holding fields for ignore_errors option
+ */
+typedef struct SafeCopyFromState
+{
+#define REPLAY_BUFFER_SIZE 1000
+ HeapTuple *replay_buffer; /* accumulates tuples for replaying it after an error */
+ int saved_tuples; /* # of tuples in replay_buffer */
+ int replayed_tuples; /* # of tuples was replayed from buffer */
+ int errors; /* total # of errors */
+ bool replay_is_active; /* if true we replay tuples from buffer */
+ bool begin_subxact; /* if true we can begin subtransaction */
+
+ MemoryContext replay_cxt;
+ MemoryContext oldcontext;
+ ResourceOwner oldowner;
+} SafeCopyFromState;
+
/*
* This struct contains all the state variables used throughout a COPY FROM
* operation.
@@ -71,6 +90,7 @@ typedef struct CopyFromStateData
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
+ SafeCopyFromState *sfcstate; /* struct for ignore_errors option */
CopyFormatOptions opts;
bool *convert_select_flags; /* per-column CSV/TEXT CS flags */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index ae35f03251..2af11bd359 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -201,6 +201,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..acf4917e64 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,135 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err_view, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 {3}"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err_view, line 6, column n: ""
+WARNING: COPY check_ign_err_view, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM trig_test;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case is in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..b25b20182e 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,122 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM trig_test;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case is in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-21 12:11 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-09-26 13:04 ` torikoshia <[email protected]>
2022-09-29 13:18 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: torikoshia @ 2022-09-26 13:04 UTC (permalink / raw)
To: Damir Belyalov <[email protected]>; +Cc: pgsql-hackers; [email protected]
On 2022-09-21 21:11, Damir Belyalov wrote:
Thanks for updating patch.
> In the previous patch there was an error when processing constraints.
> The patch was fixed, but the code grew up and became more complicated
> (0005-COPY_IGNORE_ERRORS). I also simplified the logic of
> safeNextCopyFrom().
> You asked why we need subtransactions, so the answer is in this patch.
> When processing a row that does not satisfy constraints or INSTEAD OF
> triggers, it is necessary to rollback the subtransaction and return
> the table to its original state.
> Cause of complexity, I had to abandon the constraints, triggers
> processing in and handle only errors that occur when reading the file.
> Attaching simplified patch (0006-COPY_IGNORE_ERRORS).
Do you mean you stop dealing with errors concerned with constraints and
triggers and we should review 0006-COPY_IGNORE_ERRORS?
> Tried to implement your error and could not. The result was the same
> as COPY FROM implements.
Hmm, I applied v6 patch and when canceled COPY by sending SIGINT(ctrl +
C), I faced the same situation as below.
I tested it on CentOS 8.4.
=# COPY test FROM '/home/tori/pgsql/master/10000000.data' WITH
(IGNORE_ERRORS);
^CCancel request sent
ERROR: canceling statement due to user request
CONTEXT: COPY test, line 628000: "628000 xxx"
=# SELECT 1;
ERROR: current transaction is aborted, commands ignored until end of
transaction block
=# ABORT;
FATAL: UserAbortTransactionBlock: unexpected state STARTED
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
I did the same procedure on COPY FROM without IGNORE_ERRORS and didn't
face this situation.
--
Regards,
--
Atsushi Torikoshi
NTT DATA CORPORATION
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-21 12:11 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-09-26 13:04 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
@ 2022-09-29 13:18 ` Damir Belyalov <[email protected]>
2022-10-17 10:17 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2022-09-29 13:18 UTC (permalink / raw)
To: torikoshia <[email protected]>; [email protected] <[email protected]>; pgsql-hackers
>
> Do you mean you stop dealing with errors concerned with constraints and
> triggers and we should review 0006-COPY_IGNORE_ERRORS?
>
Yes, this patch is simpler and I think it's worth adding it first.
> Hmm, I applied v6 patch and when canceled COPY by sending SIGINT(ctrl +
> C), I faced the same situation as below.
> I tested it on CentOS 8.4.
>
Thank you for pointing out this error. it really needs to be taken into
account. In the previous 0006 patch, there were 2 stages in one
subtransaction - filling the buffer and 'replay mode' (reading from the
buffer). Since only NextCopyFrom() is included in PG_TRY(), and the
ERRCODE_QUERY_CANCELED error can occur anywhere, it is impossible to catch
it and rollback the subtransaction.
I changed the 0006 patch and fixed this error and now only the 'replay
buffer filling' is made in the subtransaction.
Patch 0005 (that processed constraints) needs to be finalized, because it
requires subtransactions to rollback constraints, triggers. Therefore, it
is not possible to fix it yet. There is a decision to put for(;;) loop in
PG_TRY. It will solve the problem, but the code will be too complicated.
Attachments:
[text/x-patch] 0007-COPY_IGNORE_ERRORS.patch (22.5K, ../../CALH1LguQ5P0uZSYQFy4gJihvV11EkLx+gwxZ-+1DFq1Z6dJqbg@mail.gmail.com/3-0007-COPY_IGNORE_ERRORS.patch)
download | inline diff:
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index c25b52d0cb..22c992e6f6 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,19 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drops rows that contain malformed data while copying. These are rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows containing columns where the data type's input function raises an error.
+ Outputs warnings about rows with incorrect data (the number of warnings
+ is not more than 100) and the total number of errors.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 49924e476a..f41b25f26a 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -406,6 +406,7 @@ ProcessCopyOptions(ParseState *pstate,
bool is_from,
List *options)
{
+ bool ignore_errors_specified = false;
bool format_specified = false;
bool freeze_specified = false;
bool header_specified = false;
@@ -448,6 +449,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index e8bb168aea..caa3375758 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -106,6 +106,9 @@ static char *limit_printout_length(const char *str);
static void ClosePipeFromProgram(CopyFromState cstate);
+static bool FillReplayBuffer(CopyFromState cstate, ExprContext *econtext,
+ TupleTableSlot *myslot);
+
/*
* error context callback for COPY FROM
*
@@ -521,6 +524,177 @@ CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
miinfo->bufferedBytes += tuplen;
}
+/*
+ * Fills replay_buffer for safe copying, enables by IGNORE_ERRORS option.
+ */
+bool
+FillReplayBuffer(CopyFromState cstate, ExprContext *econtext, TupleTableSlot *myslot)
+{
+ SafeCopyFromState *sfcstate = cstate->sfcstate;
+ bool valid_row = true;
+
+ if (!sfcstate->replay_is_active)
+ {
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ while (sfcstate->saved_tuples < REPLAY_BUFFER_SIZE)
+ {
+ bool tuple_is_valid = false;
+
+ PG_TRY();
+ {
+ MemoryContext cxt = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+
+ valid_row = NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+
+ if (valid_row)
+ tuple_is_valid = true;
+
+ CurrentMemoryContext = cxt;
+ }
+ PG_CATCH();
+ {
+ MemoryContext ecxt = MemoryContextSwitchTo(sfcstate->oldcontext);
+ ErrorData *errdata = CopyErrorData();
+
+ Assert(IsSubTransaction());
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore data exceptions */
+ case ERRCODE_CHARACTER_NOT_IN_REPERTOIRE:
+ case ERRCODE_DATA_EXCEPTION:
+ case ERRCODE_ARRAY_ELEMENT_ERROR:
+ case ERRCODE_DATETIME_VALUE_OUT_OF_RANGE:
+ case ERRCODE_INTERVAL_FIELD_OVERFLOW:
+ case ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST:
+ case ERRCODE_INVALID_DATETIME_FORMAT:
+ case ERRCODE_INVALID_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_ESCAPE_SEQUENCE:
+ case ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_PARAMETER_VALUE:
+ case ERRCODE_INVALID_TABLESAMPLE_ARGUMENT:
+ case ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE:
+ case ERRCODE_NULL_VALUE_NOT_ALLOWED:
+ case ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE:
+ case ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED:
+ case ERRCODE_STRING_DATA_LENGTH_MISMATCH:
+ case ERRCODE_STRING_DATA_RIGHT_TRUNCATION:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ case ERRCODE_INVALID_BINARY_REPRESENTATION:
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_UNTRANSLATABLE_CHARACTER:
+ case ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE:
+ case ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION:
+ case ERRCODE_INVALID_JSON_TEXT:
+ case ERRCODE_INVALID_SQL_JSON_SUBSCRIPT:
+ case ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM:
+ case ERRCODE_NO_SQL_JSON_ITEM:
+ case ERRCODE_NON_NUMERIC_SQL_JSON_ITEM:
+ case ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT:
+ case ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED:
+ case ERRCODE_SQL_JSON_ARRAY_NOT_FOUND:
+ case ERRCODE_SQL_JSON_MEMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_NUMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_OBJECT_NOT_FOUND:
+ case ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS:
+ case ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS:
+ case ERRCODE_SQL_JSON_SCALAR_REQUIRED:
+ case ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE:
+ /* If the error can be processed, begin a new subtransaction */
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->errors++;
+ if (sfcstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+ break;
+ default:
+ PG_RE_THROW();
+ break;
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(ecxt);
+ }
+ PG_END_TRY();
+
+ if (tuple_is_valid)
+ {
+ /* Filling replay_buffer in Replay_context */
+ MemoryContext cxt = MemoryContextSwitchTo(sfcstate->replay_cxt);
+ HeapTuple saved_tuple;
+
+ saved_tuple = heap_form_tuple(RelationGetDescr(cstate->rel), myslot->tts_values, myslot->tts_isnull);
+ sfcstate->replay_buffer[sfcstate->saved_tuples++] = saved_tuple;
+
+ MemoryContextSwitchTo(cxt);
+ }
+
+ MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+ ExecClearTuple(myslot);
+
+ if (!valid_row)
+ break;
+ }
+
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ /* End of file or buffer was filled, prepare to replay remaining tuples from buffer */
+ sfcstate->replay_is_active = true;
+ }
+
+ if (sfcstate->replay_is_active)
+ {
+ if (sfcstate->replayed_tuples < sfcstate->saved_tuples)
+ {
+ /* Replaying the tuple */
+ MemoryContext cxt = MemoryContextSwitchTo(sfcstate->replay_cxt);
+
+ heap_deform_tuple(sfcstate->replay_buffer[sfcstate->replayed_tuples++], RelationGetDescr(cstate->rel),
+ myslot->tts_values, myslot->tts_isnull);
+ MemoryContextSwitchTo(cxt);
+ }
+ else
+ {
+ /* All tuples from buffer were replayed, clean it up */
+ MemoryContextReset(sfcstate->replay_cxt);
+ sfcstate->saved_tuples = sfcstate->replayed_tuples = 0;
+
+ sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ sfcstate->replay_is_active = false;
+
+ if (!valid_row)
+ {
+ /* All tuples were replayed */
+ if (sfcstate->errors == 0)
+ ereport(NOTICE,
+ errmsg("%d errors", sfcstate->errors));
+ else if (sfcstate->errors == 1)
+ ereport(WARNING,
+ errmsg("%d error", sfcstate->errors));
+ else
+ ereport(WARNING,
+ errmsg("%d errors", sfcstate->errors));
+
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/*
* Copy FROM file to relation.
*/
@@ -855,9 +1029,19 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
- break;
+ if (cstate->sfcstate)
+ {
+ /* If option IGNORE_ERRORS is enabled, COPY skips rows with errors */
+ if (!FillReplayBuffer(cstate, econtext, myslot))
+ break;
+
+ if (!cstate->sfcstate->replay_is_active)
+ continue;
+ }
+ else
+ /* Directly store the values/nulls array in the slot */
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
ExecStoreVirtualTuple(myslot);
@@ -1550,6 +1734,25 @@ BeginCopyFrom(ParseState *pstate,
cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
}
+ /* Initialize safeCopyFromState for IGNORE_ERRORS option */
+ if (cstate->opts.ignore_errors)
+ {
+ cstate->sfcstate = palloc(sizeof(SafeCopyFromState));
+
+ cstate->sfcstate->replay_cxt = AllocSetContextCreate(oldcontext,
+ "Replay_context",
+ ALLOCSET_DEFAULT_SIZES);
+ cstate->sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ cstate->sfcstate->saved_tuples = 0;
+ cstate->sfcstate->replayed_tuples = 0;
+ cstate->sfcstate->errors = 0;
+ cstate->sfcstate->replay_is_active = false;
+
+ cstate->sfcstate->oldowner = CurrentResourceOwner;
+ cstate->sfcstate->oldcontext = cstate->copycontext;
+ }
+
MemoryContextSwitchTo(oldcontext);
return cstate;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b5ab9d9c9a..b49954c0aa 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -808,7 +808,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3477,6 +3477,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeBoolean(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -17778,6 +17782,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -18357,6 +18362,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 62a39779b9..fe590ff7a8 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2748,7 +2748,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index cb0096aeb6..2b696f99bc 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -42,6 +42,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index e37c6032ae..d3f4c8d9df 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -16,6 +16,7 @@
#include "commands/copy.h"
#include "commands/trigger.h"
+#include "utils/resowner.h"
/*
* Represents the different source cases we need to worry about at
@@ -49,6 +50,23 @@ typedef enum CopyInsertMethod
CIM_MULTI_CONDITIONAL /* use table_multi_insert only if valid */
} CopyInsertMethod;
+/*
+ * Struct that holding fields for ignore_errors option
+ */
+typedef struct SafeCopyFromState
+{
+#define REPLAY_BUFFER_SIZE 1000
+ HeapTuple *replay_buffer; /* accumulates tuples for replaying it after an error */
+ int saved_tuples; /* # of tuples in replay_buffer */
+ int replayed_tuples; /* # of tuples was replayed from buffer */
+ int errors; /* total # of errors */
+ bool replay_is_active; /* if true we replay tuples from buffer */
+
+ MemoryContext replay_cxt;
+ MemoryContext oldcontext;
+ ResourceOwner oldowner;
+} SafeCopyFromState;
+
/*
* This struct contains all the state variables used throughout a COPY FROM
* operation.
@@ -71,6 +89,7 @@ typedef struct CopyFromStateData
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
+ SafeCopyFromState *sfcstate; /* struct for ignore_errors option */
CopyFormatOptions opts;
bool *convert_select_flags; /* per-column CSV/TEXT CS flags */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index ae35f03251..2af11bd359 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -201,6 +201,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..acf4917e64 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,135 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err_view, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 {3}"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err_view, line 6, column n: ""
+WARNING: COPY check_ign_err_view, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM trig_test;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case is in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..b25b20182e 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,122 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM trig_test;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case is in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-21 12:11 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-09-26 13:04 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-29 13:18 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-10-17 10:17 ` Damir Belyalov <[email protected]>
2022-11-02 08:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Damir Belyalov @ 2022-10-17 10:17 UTC (permalink / raw)
To: torikoshia <[email protected]>; [email protected] <[email protected]>; pgsql-hackers
Updated the patch due to conflicts when applying to master.
>
Attachments:
[text/x-patch] 0008-COPY_IGNORE_ERRORS.patch (22.5K, ../../CALH1Lgug+mR9A1bBzR8hrp2oW4=jvR_N0An-i2X_j_y9C1fkiA@mail.gmail.com/3-0008-COPY_IGNORE_ERRORS.patch)
download | inline diff:
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index c25b52d0cb..22c992e6f6 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,19 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drops rows that contain malformed data while copying. These are rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows containing columns where the data type's input function raises an error.
+ Outputs warnings about rows with incorrect data (the number of warnings
+ is not more than 100) and the total number of errors.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index db4c9dbc23..d04753a4c8 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -406,6 +406,7 @@ ProcessCopyOptions(ParseState *pstate,
bool is_from,
List *options)
{
+ bool ignore_errors_specified = false;
bool format_specified = false;
bool freeze_specified = false;
bool header_specified = false;
@@ -448,6 +449,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index a079c70152..fa169d2cf4 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -107,6 +107,9 @@ static char *limit_printout_length(const char *str);
static void ClosePipeFromProgram(CopyFromState cstate);
+static bool FillReplayBuffer(CopyFromState cstate, ExprContext *econtext,
+ TupleTableSlot *myslot);
+
/*
* error context callback for COPY FROM
*
@@ -625,6 +628,177 @@ CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
miinfo->bufferedBytes += tuplen;
}
+/*
+ * Fills replay_buffer for safe copying, enables by IGNORE_ERRORS option.
+ */
+bool
+FillReplayBuffer(CopyFromState cstate, ExprContext *econtext, TupleTableSlot *myslot)
+{
+ SafeCopyFromState *sfcstate = cstate->sfcstate;
+ bool valid_row = true;
+
+ if (!sfcstate->replay_is_active)
+ {
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ while (sfcstate->saved_tuples < REPLAY_BUFFER_SIZE)
+ {
+ bool tuple_is_valid = false;
+
+ PG_TRY();
+ {
+ MemoryContext cxt = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+
+ valid_row = NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+
+ if (valid_row)
+ tuple_is_valid = true;
+
+ CurrentMemoryContext = cxt;
+ }
+ PG_CATCH();
+ {
+ MemoryContext ecxt = MemoryContextSwitchTo(sfcstate->oldcontext);
+ ErrorData *errdata = CopyErrorData();
+
+ Assert(IsSubTransaction());
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore data exceptions */
+ case ERRCODE_CHARACTER_NOT_IN_REPERTOIRE:
+ case ERRCODE_DATA_EXCEPTION:
+ case ERRCODE_ARRAY_ELEMENT_ERROR:
+ case ERRCODE_DATETIME_VALUE_OUT_OF_RANGE:
+ case ERRCODE_INTERVAL_FIELD_OVERFLOW:
+ case ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST:
+ case ERRCODE_INVALID_DATETIME_FORMAT:
+ case ERRCODE_INVALID_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_ESCAPE_SEQUENCE:
+ case ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_PARAMETER_VALUE:
+ case ERRCODE_INVALID_TABLESAMPLE_ARGUMENT:
+ case ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE:
+ case ERRCODE_NULL_VALUE_NOT_ALLOWED:
+ case ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE:
+ case ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED:
+ case ERRCODE_STRING_DATA_LENGTH_MISMATCH:
+ case ERRCODE_STRING_DATA_RIGHT_TRUNCATION:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ case ERRCODE_INVALID_BINARY_REPRESENTATION:
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_UNTRANSLATABLE_CHARACTER:
+ case ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE:
+ case ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION:
+ case ERRCODE_INVALID_JSON_TEXT:
+ case ERRCODE_INVALID_SQL_JSON_SUBSCRIPT:
+ case ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM:
+ case ERRCODE_NO_SQL_JSON_ITEM:
+ case ERRCODE_NON_NUMERIC_SQL_JSON_ITEM:
+ case ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT:
+ case ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED:
+ case ERRCODE_SQL_JSON_ARRAY_NOT_FOUND:
+ case ERRCODE_SQL_JSON_MEMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_NUMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_OBJECT_NOT_FOUND:
+ case ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS:
+ case ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS:
+ case ERRCODE_SQL_JSON_SCALAR_REQUIRED:
+ case ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE:
+ /* If the error can be processed, begin a new subtransaction */
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->errors++;
+ if (sfcstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+ break;
+ default:
+ PG_RE_THROW();
+ break;
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(ecxt);
+ }
+ PG_END_TRY();
+
+ if (tuple_is_valid)
+ {
+ /* Filling replay_buffer in Replay_context */
+ MemoryContext cxt = MemoryContextSwitchTo(sfcstate->replay_cxt);
+ HeapTuple saved_tuple;
+
+ saved_tuple = heap_form_tuple(RelationGetDescr(cstate->rel), myslot->tts_values, myslot->tts_isnull);
+ sfcstate->replay_buffer[sfcstate->saved_tuples++] = saved_tuple;
+
+ MemoryContextSwitchTo(cxt);
+ }
+
+ MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+ ExecClearTuple(myslot);
+
+ if (!valid_row)
+ break;
+ }
+
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ /* End of file or buffer was filled, prepare to replay remaining tuples from buffer */
+ sfcstate->replay_is_active = true;
+ }
+
+ if (sfcstate->replay_is_active)
+ {
+ if (sfcstate->replayed_tuples < sfcstate->saved_tuples)
+ {
+ /* Replaying the tuple */
+ MemoryContext cxt = MemoryContextSwitchTo(sfcstate->replay_cxt);
+
+ heap_deform_tuple(sfcstate->replay_buffer[sfcstate->replayed_tuples++], RelationGetDescr(cstate->rel),
+ myslot->tts_values, myslot->tts_isnull);
+ MemoryContextSwitchTo(cxt);
+ }
+ else
+ {
+ /* All tuples from buffer were replayed, clean it up */
+ MemoryContextReset(sfcstate->replay_cxt);
+ sfcstate->saved_tuples = sfcstate->replayed_tuples = 0;
+
+ sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ sfcstate->replay_is_active = false;
+
+ if (!valid_row)
+ {
+ /* All tuples were replayed */
+ if (sfcstate->errors == 0)
+ ereport(NOTICE,
+ errmsg("%d errors", sfcstate->errors));
+ else if (sfcstate->errors == 1)
+ ereport(WARNING,
+ errmsg("%d error", sfcstate->errors));
+ else
+ ereport(WARNING,
+ errmsg("%d errors", sfcstate->errors));
+
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/*
* Copy FROM file to relation.
*/
@@ -985,9 +1159,19 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
- break;
+ if (cstate->sfcstate)
+ {
+ /* If option IGNORE_ERRORS is enabled, COPY skips rows with errors */
+ if (!FillReplayBuffer(cstate, econtext, myslot))
+ break;
+
+ if (!cstate->sfcstate->replay_is_active)
+ continue;
+ }
+ else
+ /* Directly store the values/nulls array in the slot */
+ if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ break;
ExecStoreVirtualTuple(myslot);
@@ -1695,6 +1879,25 @@ BeginCopyFrom(ParseState *pstate,
cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
}
+ /* Initialize safeCopyFromState for IGNORE_ERRORS option */
+ if (cstate->opts.ignore_errors)
+ {
+ cstate->sfcstate = palloc(sizeof(SafeCopyFromState));
+
+ cstate->sfcstate->replay_cxt = AllocSetContextCreate(oldcontext,
+ "Replay_context",
+ ALLOCSET_DEFAULT_SIZES);
+ cstate->sfcstate->replay_buffer = MemoryContextAlloc(cstate->sfcstate->replay_cxt,
+ REPLAY_BUFFER_SIZE * sizeof(HeapTuple));
+ cstate->sfcstate->saved_tuples = 0;
+ cstate->sfcstate->replayed_tuples = 0;
+ cstate->sfcstate->errors = 0;
+ cstate->sfcstate->replay_is_active = false;
+
+ cstate->sfcstate->oldowner = CurrentResourceOwner;
+ cstate->sfcstate->oldcontext = cstate->copycontext;
+ }
+
MemoryContextSwitchTo(oldcontext);
return cstate;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 737bd2d06d..b3a6c9931e 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -702,7 +702,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3359,6 +3359,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeBoolean(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -16756,6 +16760,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -17310,6 +17315,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 584d9d5ae6..33d583a94c 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2757,7 +2757,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index b77b935005..0bf9641b6e 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -42,6 +42,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index 8d9cc5accd..3289d96872 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -16,6 +16,7 @@
#include "commands/copy.h"
#include "commands/trigger.h"
+#include "utils/resowner.h"
/*
* Represents the different source cases we need to worry about at
@@ -52,6 +53,23 @@ typedef enum CopyInsertMethod
* ExecForeignBatchInsert only if valid */
} CopyInsertMethod;
+/*
+ * Struct that holding fields for ignore_errors option
+ */
+typedef struct SafeCopyFromState
+{
+#define REPLAY_BUFFER_SIZE 1000
+ HeapTuple *replay_buffer; /* accumulates tuples for replaying it after an error */
+ int saved_tuples; /* # of tuples in replay_buffer */
+ int replayed_tuples; /* # of tuples was replayed from buffer */
+ int errors; /* total # of errors */
+ bool replay_is_active; /* if true we replay tuples from buffer */
+
+ MemoryContext replay_cxt;
+ MemoryContext oldcontext;
+ ResourceOwner oldowner;
+} SafeCopyFromState;
+
/*
* This struct contains all the state variables used throughout a COPY FROM
* operation.
@@ -74,6 +92,7 @@ typedef struct CopyFromStateData
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
+ SafeCopyFromState *sfcstate; /* struct for ignore_errors option */
CopyFormatOptions opts;
bool *convert_select_flags; /* per-column CSV/TEXT CS flags */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 957ee18d84..ed25a8c86c 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -196,6 +196,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..acf4917e64 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,135 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err_view, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 {3}"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err_view, line 6, column n: ""
+WARNING: COPY check_ign_err_view, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM trig_test;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case is in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: 6 errors
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..b25b20182e 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,122 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM trig_test;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case is in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-21 12:11 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-09-26 13:04 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-29 13:18 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-10-17 10:17 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-11-02 08:46 ` Damir Belyalov <[email protected]>
2022-12-07 11:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Nikita Malakhov <[email protected]>
2022-12-09 14:25 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Danil Anisimow <[email protected]>
0 siblings, 2 replies; 94+ messages in thread
From: Damir Belyalov @ 2022-11-02 08:46 UTC (permalink / raw)
To: torikoshia <[email protected]>; [email protected] <[email protected]>; pgsql-hackers
Updated the patch:
- Optimized and simplified logic of IGNORE_ERRORS
- Changed variable names to more understandable ones
- Added an analogue of MAX_BUFFERED_BYTES for safe buffer
Regards,
Damir Belyalov
Postgres Professional
>
Attachments:
[text/x-patch] 0010-COPY_IGNORE_ERRORS.patch (22.3K, ../../CALH1LguPAN=p5wHKwGcHrjE8Vj1x4o1z3Pk228YDif6LFzbeYQ@mail.gmail.com/3-0010-COPY_IGNORE_ERRORS.patch)
download | inline diff:
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index c25b52d0cb..22c992e6f6 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -34,6 +34,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORMAT <replaceable class="parameter">format_name</replaceable>
FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ IGNORE_ERRORS [ <replaceable class="parameter">boolean</replaceable> ]
DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
NULL '<replaceable class="parameter">null_string</replaceable>'
HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
@@ -233,6 +234,19 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>IGNORE_ERRORS</literal></term>
+ <listitem>
+ <para>
+ Drops rows that contain malformed data while copying. These are rows
+ containing syntax errors in data, rows with too many or too few columns,
+ rows containing columns where the data type's input function raises an error.
+ Outputs warnings about rows with incorrect data (the number of warnings
+ is not more than 100) and the total number of errors.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>DELIMITER</literal></term>
<listitem>
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index db4c9dbc23..d04753a4c8 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -406,6 +406,7 @@ ProcessCopyOptions(ParseState *pstate,
bool is_from,
List *options)
{
+ bool ignore_errors_specified = false;
bool format_specified = false;
bool freeze_specified = false;
bool header_specified = false;
@@ -448,6 +449,13 @@ ProcessCopyOptions(ParseState *pstate,
freeze_specified = true;
opts_out->freeze = defGetBoolean(defel);
}
+ else if (strcmp(defel->defname, "ignore_errors") == 0)
+ {
+ if (ignore_errors_specified)
+ errorConflictingDefElem(defel, pstate);
+ ignore_errors_specified = true;
+ opts_out->ignore_errors = defGetBoolean(defel);
+ }
else if (strcmp(defel->defname, "delimiter") == 0)
{
if (opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index a079c70152..846eac022d 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -107,6 +107,9 @@ static char *limit_printout_length(const char *str);
static void ClosePipeFromProgram(CopyFromState cstate);
+static bool SafeCopying(CopyFromState cstate, ExprContext *econtext,
+ TupleTableSlot *myslot);
+
/*
* error context callback for COPY FROM
*
@@ -625,6 +628,175 @@ CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
miinfo->bufferedBytes += tuplen;
}
+/*
+ * Safely reads source data, converts to a tuple and fills tuple buffer.
+ * Skips some data in the case of failed conversion if data source for
+ * a next tuple can be surely read without a danger.
+ */
+bool
+SafeCopying(CopyFromState cstate, ExprContext *econtext, TupleTableSlot *myslot)
+{
+ SafeCopyFromState *sfcstate = cstate->sfcstate;
+ bool valid_row = true;
+
+ /* Standard COPY if IGNORE_ERRORS is disabled */
+ if (!cstate->sfcstate)
+ /* Directly stores the values/nulls array in the slot */
+ return NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+
+ if (sfcstate->replayed_tuples < sfcstate->saved_tuples)
+ {
+ Assert(sfcstate->saved_tuples > 0);
+
+ /* Prepare to replay the tuple */
+ heap_deform_tuple(sfcstate->safe_buffer[sfcstate->replayed_tuples++], RelationGetDescr(cstate->rel),
+ myslot->tts_values, myslot->tts_isnull);
+ return true;
+ }
+ else
+ {
+ /* All tuples from buffer were replayed, clean it up */
+ MemoryContextReset(sfcstate->safe_cxt);
+
+ sfcstate->saved_tuples = sfcstate->replayed_tuples = 0;
+ sfcstate->safeBufferBytes = 0;
+ }
+
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ while (sfcstate->saved_tuples < SAFE_BUFFER_SIZE &&
+ sfcstate->safeBufferBytes < MAX_SAFE_BUFFER_BYTES)
+ {
+ bool tuple_is_valid = true;
+
+ PG_TRY();
+ {
+ MemoryContext cxt = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
+
+ valid_row = NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull);
+ tuple_is_valid = valid_row;
+
+ if (valid_row)
+ sfcstate->safeBufferBytes += cstate->line_buf.len;
+
+ CurrentMemoryContext = cxt;
+ }
+ PG_CATCH();
+ {
+ MemoryContext ecxt = MemoryContextSwitchTo(sfcstate->oldcontext);
+ ErrorData *errdata = CopyErrorData();
+
+ tuple_is_valid = false;
+
+ Assert(IsSubTransaction());
+
+ RollbackAndReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ switch (errdata->sqlerrcode)
+ {
+ /* Ignore data exceptions */
+ case ERRCODE_CHARACTER_NOT_IN_REPERTOIRE:
+ case ERRCODE_DATA_EXCEPTION:
+ case ERRCODE_ARRAY_ELEMENT_ERROR:
+ case ERRCODE_DATETIME_VALUE_OUT_OF_RANGE:
+ case ERRCODE_INTERVAL_FIELD_OVERFLOW:
+ case ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST:
+ case ERRCODE_INVALID_DATETIME_FORMAT:
+ case ERRCODE_INVALID_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_ESCAPE_SEQUENCE:
+ case ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER:
+ case ERRCODE_INVALID_PARAMETER_VALUE:
+ case ERRCODE_INVALID_TABLESAMPLE_ARGUMENT:
+ case ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE:
+ case ERRCODE_NULL_VALUE_NOT_ALLOWED:
+ case ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE:
+ case ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED:
+ case ERRCODE_STRING_DATA_LENGTH_MISMATCH:
+ case ERRCODE_STRING_DATA_RIGHT_TRUNCATION:
+ case ERRCODE_INVALID_TEXT_REPRESENTATION:
+ case ERRCODE_INVALID_BINARY_REPRESENTATION:
+ case ERRCODE_BAD_COPY_FILE_FORMAT:
+ case ERRCODE_UNTRANSLATABLE_CHARACTER:
+ case ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE:
+ case ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION:
+ case ERRCODE_INVALID_JSON_TEXT:
+ case ERRCODE_INVALID_SQL_JSON_SUBSCRIPT:
+ case ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM:
+ case ERRCODE_NO_SQL_JSON_ITEM:
+ case ERRCODE_NON_NUMERIC_SQL_JSON_ITEM:
+ case ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT:
+ case ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED:
+ case ERRCODE_SQL_JSON_ARRAY_NOT_FOUND:
+ case ERRCODE_SQL_JSON_MEMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_NUMBER_NOT_FOUND:
+ case ERRCODE_SQL_JSON_OBJECT_NOT_FOUND:
+ case ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS:
+ case ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS:
+ case ERRCODE_SQL_JSON_SCALAR_REQUIRED:
+ case ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE:
+ /* If the error can be processed, begin a new subtransaction */
+ BeginInternalSubTransaction(NULL);
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ sfcstate->errors++;
+ if (sfcstate->errors <= 100)
+ ereport(WARNING,
+ (errcode(errdata->sqlerrcode),
+ errmsg("%s", errdata->context)));
+ break;
+ default:
+ MemoryContextSwitchTo(ecxt);
+
+ PG_RE_THROW();
+
+ break;
+ }
+
+ FlushErrorState();
+ FreeErrorData(errdata);
+ errdata = NULL;
+
+ MemoryContextSwitchTo(ecxt);
+ }
+ PG_END_TRY();
+
+ if (tuple_is_valid)
+ {
+ /* Add tuple to safe_buffer in Safe_context */
+ HeapTuple saved_tuple;
+
+ MemoryContextSwitchTo(sfcstate->safe_cxt);
+
+ saved_tuple = heap_form_tuple(RelationGetDescr(cstate->rel), myslot->tts_values, myslot->tts_isnull);
+ sfcstate->safe_buffer[sfcstate->saved_tuples++] = saved_tuple;
+ }
+
+ ExecClearTuple(myslot);
+
+ if (!valid_row)
+ break;
+ }
+
+ ReleaseCurrentSubTransaction();
+ CurrentResourceOwner = sfcstate->oldowner;
+
+ /* Prepare to replay the first tuple from safe_buffer */
+ if (sfcstate->saved_tuples != 0)
+ {
+ heap_deform_tuple(sfcstate->safe_buffer[sfcstate->replayed_tuples++], RelationGetDescr(cstate->rel),
+ myslot->tts_values, myslot->tts_isnull);
+ return true;
+ }
+
+ /* End of file and nothing to replay? */
+ if (!valid_row && sfcstate->replayed_tuples == sfcstate->saved_tuples)
+ return false;
+
+ return true;
+}
+
/*
* Copy FROM file to relation.
*/
@@ -985,8 +1157,8 @@ CopyFrom(CopyFromState cstate)
ExecClearTuple(myslot);
- /* Directly store the values/nulls array in the slot */
- if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
+ /* Standard copying with option "safe copying" enabled by IGNORE_ERRORS. */
+ if (!SafeCopying(cstate, econtext, myslot))
break;
ExecStoreVirtualTuple(myslot);
@@ -1270,6 +1442,10 @@ CopyFrom(CopyFromState cstate)
}
}
+ if (cstate->sfcstate && cstate->sfcstate->errors > 0)
+ ereport(WARNING,
+ errmsg("Errors: %d", cstate->sfcstate->errors));
+
/* Flush any remaining buffered tuples */
if (insertMethod != CIM_SINGLE)
{
@@ -1695,6 +1871,23 @@ BeginCopyFrom(ParseState *pstate,
cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
}
+ /* Initialize safeCopyFromState for IGNORE_ERRORS option */
+ if (cstate->opts.ignore_errors)
+ {
+ cstate->sfcstate = palloc(sizeof(SafeCopyFromState));
+
+ cstate->sfcstate->safe_cxt = AllocSetContextCreate(oldcontext,
+ "Safe_context",
+ ALLOCSET_DEFAULT_SIZES);
+ cstate->sfcstate->saved_tuples = 0;
+ cstate->sfcstate->replayed_tuples = 0;
+ cstate->sfcstate->safeBufferBytes = 0;
+ cstate->sfcstate->errors = 0;
+
+ cstate->sfcstate->oldowner = CurrentResourceOwner;
+ cstate->sfcstate->oldcontext = cstate->copycontext;
+ }
+
MemoryContextSwitchTo(oldcontext);
return cstate;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 737bd2d06d..b3a6c9931e 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -702,7 +702,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
HANDLER HAVING HEADER_P HOLD HOUR_P
- IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
+ IDENTITY_P IF_P IGNORE_ERRORS ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -3359,6 +3359,10 @@ copy_opt_item:
{
$$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1);
}
+ | IGNORE_ERRORS
+ {
+ $$ = makeDefElem("ignore_errors", (Node *)makeBoolean(true), @1);
+ }
| DELIMITER opt_as Sconst
{
$$ = makeDefElem("delimiter", (Node *) makeString($3), @1);
@@ -16756,6 +16760,7 @@ unreserved_keyword:
| HOUR_P
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
@@ -17310,6 +17315,7 @@ bare_label_keyword:
| HOLD
| IDENTITY_P
| IF_P
+ | IGNORE_ERRORS
| ILIKE
| IMMEDIATE
| IMMUTABLE
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 584d9d5ae6..33d583a94c 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2757,7 +2757,8 @@ psql_completion(const char *text, int start, int end)
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "("))
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
- "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING");
+ "FORCE_NOT_NULL", "FORCE_NULL", "ENCODING",
+ "IGNORE_ERRORS");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index b77b935005..0bf9641b6e 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -42,6 +42,7 @@ typedef struct CopyFormatOptions
* -1 if not specified */
bool binary; /* binary format? */
bool freeze; /* freeze rows on loading? */
+ bool ignore_errors; /* ignore rows with errors */
bool csv_mode; /* Comma Separated Value format? */
CopyHeaderChoice header_line; /* header line? */
char *null_print; /* NULL marker string (server encoding!) */
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index 8d9cc5accd..7c65157866 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -16,6 +16,7 @@
#include "commands/copy.h"
#include "commands/trigger.h"
+#include "utils/resowner.h"
/*
* Represents the different source cases we need to worry about at
@@ -52,6 +53,25 @@ typedef enum CopyInsertMethod
* ExecForeignBatchInsert only if valid */
} CopyInsertMethod;
+/*
+ * Struct that holding fields for safe copying option enabled by IGNORE_ERRORS.
+ */
+typedef struct SafeCopyFromState
+{
+#define SAFE_BUFFER_SIZE 1000
+#define MAX_SAFE_BUFFER_BYTES 65535
+
+ HeapTuple safe_buffer[SAFE_BUFFER_SIZE]; /* accumulates valid tuples */
+ int saved_tuples; /* # of tuples in safe_buffer */
+ int replayed_tuples; /* # of tuples were replayed from buffer */
+ int safeBufferBytes; /* # of bytes from all buffered tuples */
+ int errors; /* total # of errors */
+
+ MemoryContext safe_cxt;
+ MemoryContext oldcontext;
+ ResourceOwner oldowner;
+} SafeCopyFromState;
+
/*
* This struct contains all the state variables used throughout a COPY FROM
* operation.
@@ -74,6 +94,7 @@ typedef struct CopyFromStateData
char *filename; /* filename, or NULL for STDIN */
bool is_program; /* is 'filename' a program to popen? */
copy_data_source_cb data_source_cb; /* function for reading data */
+ SafeCopyFromState *sfcstate; /* struct for ignore_errors option */
CopyFormatOptions opts;
bool *convert_select_flags; /* per-column CSV/TEXT CS flags */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 957ee18d84..ed25a8c86c 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -196,6 +196,7 @@ PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("ignore_errors", IGNORE_ERRORS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 5f3685e9ef..cc6d572cf1 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -649,6 +649,135 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: Errors: 6
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: Errors: 6
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before on check_ign_err;
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err_view, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err_view, line 3: "3 {3}"
+WARNING: COPY check_ign_err_view, line 4, column n: "a"
+WARNING: COPY check_ign_err_view, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err_view, line 6, column n: ""
+WARNING: COPY check_ign_err_view, line 7, column m: "{a, 7}"
+WARNING: Errors: 6
+SELECT * FROM trig_test;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+-- foreign table case is in postgres_fdw extension
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: Errors: 6
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+(1 row)
+
+DROP TABLE check_ign_err;
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+WARNING: COPY check_ign_err, line 2: "2 {2} 2 2"
+WARNING: COPY check_ign_err, line 3: "3 {3}"
+WARNING: COPY check_ign_err, line 4, column n: "a"
+WARNING: COPY check_ign_err, line 5, column k: "5555555555"
+WARNING: COPY check_ign_err, line 6, column n: ""
+WARNING: COPY check_ign_err, line 7, column m: "{a, 7}"
+WARNING: Errors: 6
+SELECT * FROM check_ign_err;
+ n | m | k
+---+-----+---
+ 1 | {1} | 1
+ 8 | {8} | 8
+(2 rows)
+
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index b3c16af48e..b25b20182e 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -454,6 +454,122 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
+-- tests for IGNORE_ERRORS option
+-- CIM_MULTI case
+CREATE TABLE check_ign_err (n int, m int[], k int);
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+
+-- CIM_SINGLE cases
+-- BEFORE row trigger
+TRUNCATE check_ign_err;
+CREATE TABLE trig_test(n int, m int[], k int);
+CREATE FUNCTION fn_trig_before () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before on check_ign_err;
+
+-- INSTEAD OF row trigger
+TRUNCATE check_ign_err;
+TRUNCATE trig_test;
+CREATE VIEW check_ign_err_view AS SELECT * FROM check_ign_err;
+CREATE FUNCTION fn_trig_instead_of () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m, NEW.k);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_instead_of INSTEAD OF INSERT ON check_ign_err_view
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_instead_of();
+COPY check_ign_err_view FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM trig_test;
+DROP TRIGGER trig_instead_of ON check_ign_err_view;
+DROP VIEW check_ign_err_view;
+
+-- foreign table case is in postgres_fdw extension
+
+-- volatile function in WHERE clause
+TRUNCATE check_ign_err;
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS
+ WHERE n = floor(random()*(1-1+1))+1; /* finds values equal 1 */
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TABLE check_ign_err;
+
+-- CIM_MULTI_CONDITIONAL case
+-- INSERT triggers for partition tables
+TRUNCATE trig_test;
+CREATE TABLE check_ign_err (n int, m int[], k int)
+ PARTITION BY RANGE (k);
+CREATE TABLE check_ign_err_part1 PARTITION OF check_ign_err
+ FOR VALUES FROM (1) TO (4);
+CREATE TABLE check_ign_err_part2 PARTITION OF check_ign_err
+ FOR VALUES FROM (4) TO (9);
+CREATE FUNCTION fn_trig_before_part () RETURNS TRIGGER AS '
+ BEGIN
+ INSERT INTO trig_test VALUES(NEW.n, NEW.m);
+ RETURN NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trig_before_part BEFORE INSERT ON check_ign_err
+FOR EACH ROW EXECUTE PROCEDURE fn_trig_before_part();
+COPY check_ign_err FROM STDIN WITH IGNORE_ERRORS WHERE n < 9;
+1 {1} 1
+2 {2} 2 2
+3 {3}
+a {4} 4
+5 {5} 5555555555
+
+7 {a, 7} 7
+8 {8} 8
+\.
+SELECT * FROM check_ign_err;
+DROP TRIGGER trig_before_part on check_ign_err;
+DROP TABLE trig_test;
+DROP TABLE check_ign_err CASCADE;
+
-- clean up
DROP TABLE forcetest;
DROP TABLE vistest;
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-21 12:11 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-09-26 13:04 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-29 13:18 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-10-17 10:17 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-11-02 08:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-12-07 11:15 ` Nikita Malakhov <[email protected]>
1 sibling, 0 replies; 94+ messages in thread
From: Nikita Malakhov @ 2022-12-07 11:15 UTC (permalink / raw)
To: Damir Belyalov <[email protected]>; +Cc: torikoshia <[email protected]>; [email protected] <[email protected]>; pgsql-hackers
Hi Damir!
Your work looks like a very promising feature for production systems,
where data often needs to be loaded from external sources.
I've looked over the discussion and want to make a proposal -
when we load a bunch of records in database it does not make sense
to output errors to command output, and does not make sense to limit
error output to any number at all, because if we decided to load data
anyway - we would want to have a list (a file) with all records that were
discarded because of errors, with related error information, to, say,
deal with errors and process these records later. It looks like a reasonable
addition to your patch.
As a command output some limited number of error messages has much
less meaning than overall stats - records processed, records loaded,
records discarded, total number of errors.
For example you can look the Oracle SQL Loader feature, I hope this could
give some ideas for further improvements.
On Wed, Nov 2, 2022 at 11:46 AM Damir Belyalov <[email protected]> wrote:
> Updated the patch:
> - Optimized and simplified logic of IGNORE_ERRORS
> - Changed variable names to more understandable ones
> - Added an analogue of MAX_BUFFERED_BYTES for safe buffer
>
>
> Regards,
> Damir Belyalov
> Postgres Professional
>
>>
--
Regards,
Nikita Malakhov
Postgres Professional
https://postgrespro.ru/
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-15 12:29 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-15 13:23 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-22 12:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-08-24 16:54 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-08-29 13:02 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-21 12:11 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-09-26 13:04 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2022-09-29 13:18 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-10-17 10:17 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
2022-11-02 08:46 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Damir Belyalov <[email protected]>
@ 2022-12-09 14:25 ` Danil Anisimow <[email protected]>
1 sibling, 0 replies; 94+ messages in thread
From: Danil Anisimow @ 2022-12-09 14:25 UTC (permalink / raw)
To: Damir Belyalov <[email protected]>; +Cc: torikoshia <[email protected]>; [email protected] <[email protected]>; pgsql-hackers
Hi!
I have looked at your patch and have a few questions.
110: static bool SafeCopying(CopyFromState cstate, ExprContext *econtext,
111: TupleTableSlot *myslot);
---
636: bool
637: SafeCopying(CopyFromState cstate, ExprContext *econtext,
TupleTableSlot *myslot)
Why is there no static keyword in the definition of the SafeCopying()
function, but it is in the function declaration.
675: MemoryContext cxt =
MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
676:
677: valid_row = NextCopyFrom(cstate, econtext, myslot->tts_values,
myslot->tts_isnull);
678: tuple_is_valid = valid_row;
679:
680: if (valid_row)
681: sfcstate->safeBufferBytes += cstate->line_buf.len;
682:
683: CurrentMemoryContext = cxt;
Why are you using a direct assignment to CurrentMemoryContext instead of
using the MemoryContextSwitchTo function in the SafeCopying() routine?
1160: /* Standard copying with option "safe copying" enabled by
IGNORE_ERRORS. */
1161: if (!SafeCopying(cstate, econtext, myslot))
1162: break;
I checked with GDB that the CurrentMemoryContext changes when SafeCopying
returns. And the target context may be different each time you do a COPY in
psql.
1879: cstate->sfcstate->safe_cxt = AllocSetContextCreate(oldcontext,
1880: "Safe_context",
1881: ALLOCSET_DEFAULT_SIZES);
When you initialize the cstate->sfcstate structure, you create a
cstate->sfcstate->safe_cxt memory context that inherits from oldcontext.
Was it intended to use cstate->copycontext as the parent context here?
On Wed, Nov 2, 2022 at 11:46 AM Damir Belyalov <[email protected]> wrote:
> Updated the patch:
> - Optimized and simplified logic of IGNORE_ERRORS
> - Changed variable names to more understandable ones
> - Added an analogue of MAX_BUFFERED_BYTES for safe buffer
>
>
> Regards,
> Damir Belyalov
> Postgres Professional
>
Regards,
Daniil Anisimov
Postgres Professional
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
@ 2022-08-24 22:47 Zhihong Yu <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Zhihong Yu @ 2022-08-24 22:47 UTC (permalink / raw)
To: PostgreSQL Developers <[email protected]>
Hi,
I was looking at 0004-COPY_IGNORE_ERRORS.patch
+ * Ignore constraints if IGNORE_ERRORS is enabled
+ */
+static void
+safeExecConstraints(CopyFromState cstate, ResultRelInfo *resultRelInfo,
TupleTableSlot *myslot, EState *estate)
I think the existing ExecConstraints() can be expanded by
checking cstate->opts.ignore_errors so that it can selectively
ignore Constraint Violations.
This way you don't need safeExecConstraints().
Cheers
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v1 4/7] Row pattern recognition patch (executor).
@ 2023-06-25 11:48 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-06-25 11:48 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 223 +++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 274 ++++++++++++++++++++++++++-
src/include/catalog/pg_proc.dat | 9 +
src/include/nodes/execnodes.h | 12 ++
src/include/windowapi.h | 9 +
5 files changed, 517 insertions(+), 10 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..ae997dff86 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -48,6 +48,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +160,14 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Map between Var attno in a target list and the parsed attno.
+ */
+typedef struct AttnoMap {
+ List *attno; /* att number in target list (list of AttNumber) */
+ List *attnosyn; /* parsed att number (list of AttNumber) */
+} AttnoMap;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -195,9 +204,9 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static void attno_map(Node *node, AttnoMap *map);
+static bool attno_map_walker(Node *node, void *context);
/*
* initialize_windowaggregate
@@ -2388,6 +2397,12 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+ Var *var;
+ int nargs;
+ AttnoMap attnomap;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2498,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2692,69 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+
+ /*
+ * Collect mapping between varattno and varattnosyn in the targetlist.
+ * XXX: For now we only check RPR's argument. Eventually we have to
+ * recurse the targetlist to find out all mappings in Var nodes.
+ */
+ attnomap.attno = NIL;
+ attnomap.attnosyn = NIL;
+
+ foreach (l, node->plan.targetlist)
+ {
+ te = lfirst(l);
+ if (IsA(te->expr, WindowFunc))
+ {
+ WindowFunc *func = (WindowFunc *)te->expr;
+ if (func->winfnoid != F_RPR)
+ continue;
+
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "RPR must have 1 argument but function %d has %d args", func->winfnoid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "RPR's arg is not Var");
+
+ var = (Var *)expr;
+ elog(DEBUG1, "resname: %s varattno: %d varattnosyn: %d",
+ te->resname, var->varattno, var->varattnosyn);
+ attnomap.attno = lappend_int(attnomap.attno, var->varattno);
+ attnomap.attnosyn = lappend_int(attnomap.attnosyn, var->varattnosyn);
+ }
+ }
+
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ /* tweak expr so that it referes to outer slot */
+ attno_map((Node *)expr, &attnomap);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2762,76 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite Var node's varattno to the varattno which is used in the target
+ * list using AttnoMap. We also rewrite varno so that it sees outer tuple
+ * (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node, AttnoMap *map)
+{
+ (void) expression_tree_walker(node, attno_map_walker, (void *) map);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+ AttnoMap *attnomap;
+ ListCell *lc1, *lc2;
+
+ if (node == NULL)
+ return false;
+
+ attnomap = (AttnoMap *) context;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ var->varno = OUTER_VAR;
+ else
+ var->varno = INNER_VAR;
+ }
+ return expression_tree_walker(node, attno_map_walker, (void *) context);
+ }
+ else if (IsA(node, Var))
+ {
+ var = (Var *)node;
+
+ elog(DEBUG1, "original varno: %d varattno: %d", var->varno, var->varattno);
+
+ forboth(lc1, attnomap->attno, lc2, attnomap->attnosyn)
+ {
+ int attno = lfirst_int(lc1);
+ int attnosyn = lfirst_int(lc2);
+
+ if (var->varattno == attnosyn)
+ {
+ elog(DEBUG1, "loc: %d rewrite varattno from: %d to %d", var->location, attnosyn, attno);
+ var->varattno = attno;
+ }
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, (void *) context);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2849,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2900,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3080,7 +3242,7 @@ are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
*
* Returns true if successful, false if no such row
*/
-static bool
+bool
window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
{
WindowAggState *winstate = winobj->winstate;
@@ -3420,14 +3582,53 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3583,15 +3784,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3821,9 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+WindowAggState *
+WinGetAggState(WindowObject winobj)
+{
+ return winobj->winstate;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..63b225271c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -39,7 +42,9 @@ typedef struct
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
+static bool get_slots(WindowObject winobj, WindowAggState *winstate, int current_pos);
+static int evaluate_pattern(WindowObject winobj, WindowAggState *winstate,
+ int relpos, char *vname, char *quantifier, bool *result);
/*
* utility routine for *_rank functions.
@@ -713,3 +718,270 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * rpr
+ * allow to use "Row pattern recognition: WINDOW clause" (SQL:2016 R020) in
+ * the target list.
+ * Usage: SELECT rpr(colname) OVER (..)
+ * where colname is defined in PATTERN clause.
+ */
+Datum
+window_rpr(PG_FUNCTION_ARGS)
+{
+#define MAX_PATTERNS 16 /* max variables in PATTERN clause */
+
+ WindowObject winobj = PG_WINDOW_OBJECT();
+ WindowAggState *winstate = WinGetAggState(winobj);
+ Datum result;
+ bool expression_result;
+ bool isnull;
+ int relpos;
+ int64 curr_pos, markpos;
+ ListCell *lc, *lc1;
+
+ curr_pos = WinGetCurrentPosition(winobj);
+ elog(DEBUG1, "rpr is called. row: " INT64_FORMAT, curr_pos);
+
+ /*
+ * Evaluate PATTERN until one of expressions is not true or out of frame.
+ */
+ relpos = 0;
+
+ forboth(lc, winstate->patternVariableList, lc1, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc));
+ char *quantifier = strVal(lfirst(lc1));
+
+ elog(DEBUG1, "relpos: %d pattern vname: %s quantifier: %s", relpos, vname, quantifier);
+
+ /* evaluate row pattern against current row */
+ relpos = evaluate_pattern(winobj, winstate, relpos, vname, quantifier, &expression_result);
+
+ /*
+ * If the expression did not match, we are done.
+ */
+ if (!expression_result)
+ break;
+
+ /* out of frame? */
+ if (relpos < 0)
+ break;
+
+ /* count up relative row position */
+ relpos++;
+ }
+
+ elog(DEBUG1, "relpos: %d", relpos);
+
+ /*
+ * If current row satified the pattern, return argument expression.
+ */
+ if (expression_result)
+ {
+ result = WinGetFuncArgInFrame(winobj, 0,
+ 0, WINDOW_SEEK_HEAD, false,
+ &isnull, NULL);
+ }
+
+ /*
+ * At this point we can set mark down to current pos -2.
+ */
+ markpos = curr_pos -2;
+ elog(DEBUG1, "markpos: " INT64_FORMAT, markpos);
+ if (markpos >= 0)
+ WinSetMarkPosition(winobj, markpos);
+
+ if (expression_result)
+ PG_RETURN_DATUM(result);
+
+ PG_RETURN_NULL();
+}
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match relative row position
+ * -1: current row is out of frame
+ */
+static
+int evaluate_pattern(WindowObject winobj, WindowAggState *winstate,
+ int relpos, char *vname, char *quantifier, bool *result)
+{
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2;
+ ExprState *pat;
+ Datum eval_result;
+ int sts;
+ bool out_of_frame = false;
+ bool isnull;
+ StringInfo encoded_str = makeStringInfo();
+ char pattern_str[128];
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList)
+ {
+ char *name = strVal(lfirst(lc1));
+ bool second_try_match = false;
+
+ if (strcmp(vname, name))
+ continue;
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ for (;;)
+ {
+ if (!get_slots(winobj, winstate, relpos))
+ {
+ out_of_frame = true;
+ break; /* current row is out of frame */
+ }
+
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: %d", vname, relpos);
+ break;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: %d", vname, relpos);
+ break;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: %d", vname, relpos);
+ appendStringInfoChar(encoded_str, vname[0]);
+
+ /* If quantifier is "+", we need to look for more matching row */
+ if (quantifier && !strcmp(quantifier, "+"))
+ {
+ /* remember that we want to try another row */
+ second_try_match = true;
+ relpos++;
+ }
+ else
+ break;
+ }
+ }
+ }
+ if (second_try_match)
+ relpos--;
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+
+ /* build regular expression */
+ snprintf(pattern_str, sizeof(pattern_str), "%c%s", vname[0], quantifier);
+
+ /*
+ * Do regular expression matching against sequence of rows satisfying
+ * the expression using regexp_instr().
+ */
+ sts = DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str->data)),
+ PointerGetDatum(cstring_to_text(pattern_str))));
+ elog(DEBUG1, "regexp_instr returned: %d. str: %s regexp: %s",
+ sts, encoded_str->data, pattern_str);
+ *result = (sts > 0)? true : false;
+ }
+ return relpos;
+}
+
+/*
+ * Get current, previous and next tuple.
+ * Returns true if still within frame.
+ */
+static bool
+get_slots(WindowObject winobj, WindowAggState *winstate, int current_pos)
+{
+ TupleTableSlot *slot;
+ bool isnull, isout;
+ int sts;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* for current row */
+ slot = winstate->temp_slot_1;
+ sts = WinGetSlotInFrame(winobj, slot,
+ current_pos, WINDOW_SEEK_HEAD, false,
+ &isnull, &isout);
+ if (sts < 0)
+ {
+ elog(DEBUG1, "current row is out of frame");
+ econtext->ecxt_scantuple = winstate->null_slot;
+ return false;
+ }
+ else
+ econtext->ecxt_scantuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ sts = WinGetSlotInFrame(winobj, slot,
+ current_pos - 1, WINDOW_SEEK_HEAD, false,
+ &isnull, &isout);
+ if (sts < 0)
+ {
+ elog(DEBUG1, "previous row out of frame at: %d", current_pos);
+ econtext->ecxt_outertuple = winstate->null_slot;
+ }
+ econtext->ecxt_outertuple = slot;
+ }
+ else
+ econtext->ecxt_outertuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ sts = WinGetSlotInFrame(winobj, slot,
+ current_pos + 1, WINDOW_SEEK_HEAD, false,
+ &isnull, &isout);
+ if (sts < 0)
+ {
+ elog(DEBUG1, "next row out of frame at: %d", current_pos);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+
+ return true;
+}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989..e3a9e0ffeb 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10397,6 +10397,15 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'row pattern recognition in window',
+ proname => 'rpr', prokind => 'w', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_rpr' },
+{ oid => '6123', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6124', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..bc95c5fe9b 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2519,6 +2519,13 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('*', '+' or '?'. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2562,11 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
} WindowAggState;
/* ----------------
diff --git a/src/include/windowapi.h b/src/include/windowapi.h
index b8c2c565d1..a0facf38fe 100644
--- a/src/include/windowapi.h
+++ b/src/include/windowapi.h
@@ -58,7 +58,16 @@ extern Datum WinGetFuncArgInFrame(WindowObject winobj, int argno,
int relpos, int seektype, bool set_mark,
bool *isnull, bool *isout);
+extern int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+
extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno,
bool *isnull);
+extern WindowAggState *WinGetAggState(WindowObject winobj);
+
+extern bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+
#endif /* WINDOWAPI_H */
--
2.25.1
----Next_Part(Sun_Jun_25_21_05_09_2023_126)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v1-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v2 4/7] Row pattern recognition patch (executor).
@ 2023-06-26 08:05 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-06-26 08:05 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 225 +++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 302 ++++++++++++++++++++++++++-
src/include/catalog/pg_proc.dat | 9 +
src/include/nodes/execnodes.h | 13 ++
src/include/windowapi.h | 9 +
5 files changed, 548 insertions(+), 10 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..bef2bc62b2 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -48,6 +48,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +160,14 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Map between Var attno in a target list and the parsed attno.
+ */
+typedef struct AttnoMap {
+ List *attno; /* att number in target list (list of AttNumber) */
+ List *attnosyn; /* parsed att number (list of AttNumber) */
+} AttnoMap;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -195,9 +204,9 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static void attno_map(Node *node, AttnoMap *map);
+static bool attno_map_walker(Node *node, void *context);
/*
* initialize_windowaggregate
@@ -2388,6 +2397,12 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+ Var *var;
+ int nargs;
+ AttnoMap attnomap;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2498,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2692,71 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+
+ /*
+ * Collect mapping between varattno and varattnosyn in the targetlist.
+ * XXX: For now we only check RPR's argument. Eventually we have to
+ * recurse the targetlist to find out all mappings in Var nodes.
+ */
+ attnomap.attno = NIL;
+ attnomap.attnosyn = NIL;
+
+ foreach (l, node->plan.targetlist)
+ {
+ te = lfirst(l);
+ if (IsA(te->expr, WindowFunc))
+ {
+ WindowFunc *func = (WindowFunc *)te->expr;
+ if (func->winfnoid != F_RPR)
+ continue;
+
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "RPR must have 1 argument but function %d has %d args", func->winfnoid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "RPR's arg is not Var");
+
+ var = (Var *)expr;
+ elog(DEBUG1, "resname: %s varattno: %d varattnosyn: %d",
+ te->resname, var->varattno, var->varattnosyn);
+ attnomap.attno = lappend_int(attnomap.attno, var->varattno);
+ attnomap.attnosyn = lappend_int(attnomap.attnosyn, var->varattnosyn);
+ }
+ }
+
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ /* tweak expr so that it referes to outer slot */
+ attno_map((Node *)expr, &attnomap);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2764,76 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite Var node's varattno to the varattno which is used in the target
+ * list using AttnoMap. We also rewrite varno so that it sees outer tuple
+ * (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node, AttnoMap *map)
+{
+ (void) expression_tree_walker(node, attno_map_walker, (void *) map);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+ AttnoMap *attnomap;
+ ListCell *lc1, *lc2;
+
+ if (node == NULL)
+ return false;
+
+ attnomap = (AttnoMap *) context;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ var->varno = OUTER_VAR;
+ else
+ var->varno = INNER_VAR;
+ }
+ return expression_tree_walker(node, attno_map_walker, (void *) context);
+ }
+ else if (IsA(node, Var))
+ {
+ var = (Var *)node;
+
+ elog(DEBUG1, "original varno: %d varattno: %d", var->varno, var->varattno);
+
+ forboth(lc1, attnomap->attno, lc2, attnomap->attnosyn)
+ {
+ int attno = lfirst_int(lc1);
+ int attnosyn = lfirst_int(lc2);
+
+ if (var->varattno == attnosyn)
+ {
+ elog(DEBUG1, "loc: %d rewrite varattno from: %d to %d", var->location, attnosyn, attno);
+ var->varattno = attno;
+ }
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, (void *) context);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2851,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2902,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3080,7 +3244,7 @@ are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
*
* Returns true if successful, false if no such row
*/
-static bool
+bool
window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
{
WindowAggState *winstate = winobj->winstate;
@@ -3420,14 +3584,53 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3583,15 +3786,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3823,9 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+WindowAggState *
+WinGetAggState(WindowObject winobj)
+{
+ return winobj->winstate;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..74ef11ce55 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,10 +39,21 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
+static bool get_slots(WindowObject winobj, WindowAggState *winstate, int current_pos);
+static int evaluate_pattern(WindowObject winobj, WindowAggState *winstate,
+ int relpos, char *vname, char *quantifier, bool *result);
/*
* utility routine for *_rank functions.
@@ -713,3 +727,289 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * rpr
+ * allow to use "Row pattern recognition: WINDOW clause" (SQL:2016 R020) in
+ * the target list.
+ * Usage: SELECT rpr(colname) OVER (..)
+ * where colname is defined in PATTERN clause.
+ */
+Datum
+window_rpr(PG_FUNCTION_ARGS)
+{
+#define MAX_PATTERNS 16 /* max variables in PATTERN clause */
+
+ WindowObject winobj = PG_WINDOW_OBJECT();
+ WindowAggState *winstate = WinGetAggState(winobj);
+ Datum result;
+ bool expression_result;
+ bool isnull;
+ int relpos;
+ int64 curr_pos, markpos;
+ ListCell *lc, *lc1;
+ SkipContext *context = NULL;
+
+ curr_pos = WinGetCurrentPosition(winobj);
+ elog(DEBUG1, "rpr is called. row: " INT64_FORMAT, curr_pos);
+
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW)
+ {
+ context = (SkipContext *) WinGetPartitionLocalMemory(winobj, sizeof(SkipContext));
+ if (curr_pos < context->pos)
+ {
+ elog(DEBUG1, "skip this row: curr_pos: " INT64_FORMAT "context->pos: " INT64_FORMAT,
+ curr_pos, context->pos);
+ PG_RETURN_NULL();
+ }
+ }
+
+ /*
+ * Evaluate PATTERN until one of expressions is not true or out of frame.
+ */
+ relpos = 0;
+
+ forboth(lc, winstate->patternVariableList, lc1, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc));
+ char *quantifier = strVal(lfirst(lc1));
+
+ elog(DEBUG1, "relpos: %d pattern vname: %s quantifier: %s", relpos, vname, quantifier);
+
+ /* evaluate row pattern against current row */
+ relpos = evaluate_pattern(winobj, winstate, relpos, vname, quantifier, &expression_result);
+
+ /*
+ * If the expression did not match, we are done.
+ */
+ if (!expression_result)
+ break;
+
+ /* out of frame? */
+ if (relpos < 0)
+ break;
+
+ /* count up relative row position */
+ relpos++;
+ }
+
+ elog(DEBUG1, "relpos: %d", relpos);
+
+ /*
+ * If current row satified the pattern, return argument expression.
+ */
+ if (expression_result)
+ {
+ result = WinGetFuncArgInFrame(winobj, 0,
+ 0, WINDOW_SEEK_HEAD, false,
+ &isnull, NULL);
+ }
+
+ /*
+ * At this point we can set mark down to current pos -2.
+ */
+ markpos = curr_pos -2;
+ elog(DEBUG1, "markpos: " INT64_FORMAT, markpos);
+ if (markpos >= 0)
+ WinSetMarkPosition(winobj, markpos);
+
+ if (expression_result)
+ {
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW)
+ {
+ context->pos += relpos;
+ elog(DEBUG1, "context->pos: " INT64_FORMAT, context->pos);
+ }
+ PG_RETURN_DATUM(result);
+ }
+
+ PG_RETURN_NULL();
+}
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match relative row position
+ * -1: current row is out of frame
+ */
+static
+int evaluate_pattern(WindowObject winobj, WindowAggState *winstate,
+ int relpos, char *vname, char *quantifier, bool *result)
+{
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2;
+ ExprState *pat;
+ Datum eval_result;
+ int sts;
+ bool out_of_frame = false;
+ bool isnull;
+ StringInfo encoded_str = makeStringInfo();
+ char pattern_str[128];
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList)
+ {
+ char *name = strVal(lfirst(lc1));
+ bool second_try_match = false;
+
+ if (strcmp(vname, name))
+ continue;
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ for (;;)
+ {
+ if (!get_slots(winobj, winstate, relpos))
+ {
+ out_of_frame = true;
+ break; /* current row is out of frame */
+ }
+
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: %d", vname, relpos);
+ break;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: %d", vname, relpos);
+ break;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: %d", vname, relpos);
+ appendStringInfoChar(encoded_str, vname[0]);
+
+ /* If quantifier is "+", we need to look for more matching row */
+ if (quantifier && !strcmp(quantifier, "+"))
+ {
+ /* remember that we want to try another row */
+ second_try_match = true;
+ relpos++;
+ }
+ else
+ break;
+ }
+ }
+ }
+ if (second_try_match)
+ relpos--;
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+
+ /* build regular expression */
+ snprintf(pattern_str, sizeof(pattern_str), "%c%s", vname[0], quantifier);
+
+ /*
+ * Do regular expression matching against sequence of rows satisfying
+ * the expression using regexp_instr().
+ */
+ sts = DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str->data)),
+ PointerGetDatum(cstring_to_text(pattern_str))));
+ elog(DEBUG1, "regexp_instr returned: %d. str: %s regexp: %s",
+ sts, encoded_str->data, pattern_str);
+ *result = (sts > 0)? true : false;
+ }
+ return relpos;
+}
+
+/*
+ * Get current, previous and next tuple.
+ * Returns true if still within frame.
+ */
+static bool
+get_slots(WindowObject winobj, WindowAggState *winstate, int current_pos)
+{
+ TupleTableSlot *slot;
+ bool isnull, isout;
+ int sts;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* for current row */
+ slot = winstate->temp_slot_1;
+ sts = WinGetSlotInFrame(winobj, slot,
+ current_pos, WINDOW_SEEK_HEAD, false,
+ &isnull, &isout);
+ if (sts < 0)
+ {
+ elog(DEBUG1, "current row is out of frame");
+ econtext->ecxt_scantuple = winstate->null_slot;
+ return false;
+ }
+ else
+ econtext->ecxt_scantuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ sts = WinGetSlotInFrame(winobj, slot,
+ current_pos - 1, WINDOW_SEEK_HEAD, false,
+ &isnull, &isout);
+ if (sts < 0)
+ {
+ elog(DEBUG1, "previous row out of frame at: %d", current_pos);
+ econtext->ecxt_outertuple = winstate->null_slot;
+ }
+ econtext->ecxt_outertuple = slot;
+ }
+ else
+ econtext->ecxt_outertuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ sts = WinGetSlotInFrame(winobj, slot,
+ current_pos + 1, WINDOW_SEEK_HEAD, false,
+ &isnull, &isout);
+ if (sts < 0)
+ {
+ elog(DEBUG1, "next row out of frame at: %d", current_pos);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+
+ return true;
+}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989..e3a9e0ffeb 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10397,6 +10397,15 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'row pattern recognition in window',
+ proname => 'rpr', prokind => 'w', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_rpr' },
+{ oid => '6123', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6124', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..1643eaa6f1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2519,6 +2519,14 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2563,11 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
} WindowAggState;
/* ----------------
diff --git a/src/include/windowapi.h b/src/include/windowapi.h
index b8c2c565d1..a0facf38fe 100644
--- a/src/include/windowapi.h
+++ b/src/include/windowapi.h
@@ -58,7 +58,16 @@ extern Datum WinGetFuncArgInFrame(WindowObject winobj, int argno,
int relpos, int seektype, bool set_mark,
bool *isnull, bool *isout);
+extern int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+
extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno,
bool *isnull);
+extern WindowAggState *WinGetAggState(WindowObject winobj);
+
+extern bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+
#endif /* WINDOWAPI_H */
--
2.25.1
----Next_Part(Mon_Jun_26_17_45_07_2023_724)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v2-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v3 4/7] Row pattern recognition patch (executor).
@ 2023-07-26 10:49 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-07-26 10:49 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 701 ++++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 38 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 18 +
src/include/windowapi.h | 8 +
5 files changed, 758 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..0586bf57d6 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,14 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Map between Var attno in a target list and the parsed attno.
+ */
+typedef struct AttnoMap {
+ List *attno; /* att number in target list (list of AttNumber) */
+ List *attnosyn; /* parsed att number (list of AttNumber) */
+} AttnoMap;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -182,8 +192,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +206,19 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static void attno_map(Node *node, AttnoMap *map);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringInfo *str_set, int set_size);
+static void search_str_set_recurse(char *pattern, StringInfo *str_set, int set_size, int set_index,
+ char *encoded_str, int *resultlen);
/*
* initialize_windowaggregate
@@ -673,6 +694,9 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool reduced_frame_set;
+ bool check_reduced_frame;
+ int num_rows_in_reduced_frame;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -790,6 +814,7 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
winstate->aggregatedupto <= winstate->frameheadpos)
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +886,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -919,6 +946,10 @@ eval_windowaggregates(WindowAggState *winstate)
ExecClearTuple(agg_row_slot);
}
+ reduced_frame_set = false;
+ check_reduced_frame = false;
+ num_rows_in_reduced_frame = 0;
+
/*
* Advance until we reach a row not in frame (or end of partition).
*
@@ -930,12 +961,18 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
if (!window_gettupleslot(agg_winobj, winstate->aggregatedupto,
agg_row_slot))
+ {
+ if (check_reduced_frame)
+ winstate->aggregatedupto--;
break; /* must be end of partition */
+ }
}
/*
@@ -944,10 +981,47 @@ eval_windowaggregates(WindowAggState *winstate)
*/
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
+ {
+ if (winstate->patternVariableList != NIL && check_reduced_frame)
+ winstate->aggregatedupto--;
break;
+ }
if (ret == 0)
goto next_tuple;
+ if (winstate->patternVariableList != NIL)
+ {
+ if (!reduced_frame_set)
+ {
+ num_rows_in_reduced_frame = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ reduced_frame_set = true;
+ elog(DEBUG1, "set num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+
+ if (num_rows_in_reduced_frame <= 0)
+ break;
+
+ else if (num_rows_in_reduced_frame > 0)
+ check_reduced_frame = true;
+ }
+
+ if (check_reduced_frame)
+ {
+ elog(DEBUG1, "decrease num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+ num_rows_in_reduced_frame--;
+ if (num_rows_in_reduced_frame < 0)
+ {
+ /*
+ * No more rows remain in the reduced frame. Finish
+ * accumulating row into the aggregates.
+ */
+ winstate->aggregatedupto--;
+ break;
+ }
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1050,8 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+ elog(DEBUG1, "===== break loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -2053,6 +2129,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2388,6 +2466,12 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+ Var *var;
+ int nargs;
+ AttnoMap attnomap;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2567,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2761,69 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+
+ /*
+ * Collect mapping between varattno and varattnosyn in the targetlist.
+ * XXX: For now we only check RPR's argument. Eventually we have to
+ * recurse the targetlist to find out all mappings in Var nodes.
+ */
+ attnomap.attno = NIL;
+ attnomap.attnosyn = NIL;
+
+ foreach (l, node->plan.targetlist)
+ {
+ te = lfirst(l);
+ if (IsA(te->expr, WindowFunc))
+ {
+ WindowFunc *func = (WindowFunc *)te->expr;
+
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (nargs != 1)
+ continue;
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ continue;
+
+ var = (Var *)expr;
+ elog(DEBUG1, "resname: %s varattno: %d varattnosyn: %d",
+ te->resname, var->varattno, var->varattnosyn);
+ attnomap.attno = lappend_int(attnomap.attno, var->varattno);
+ attnomap.attnosyn = lappend_int(attnomap.attnosyn, var->varattnosyn);
+ }
+ }
+
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ /* tweak expr so that it referes to outer slot */
+ attno_map((Node *)expr, &attnomap);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2831,77 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite Var node's varattno to the varattno which is used in the target
+ * list using AttnoMap. We also rewrite varno so that it sees outer tuple
+ * (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node, AttnoMap *map)
+{
+ (void) expression_tree_walker(node, attno_map_walker, (void *) map);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+ AttnoMap *attnomap;
+ ListCell *lc1, *lc2;
+
+ if (node == NULL)
+ return false;
+
+ attnomap = (AttnoMap *) context;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ var->varno = OUTER_VAR;
+ else
+ var->varno = INNER_VAR;
+ }
+ return expression_tree_walker(node, attno_map_walker, (void *) context);
+ }
+ else if (IsA(node, Var))
+ {
+ var = (Var *)node;
+
+ elog(DEBUG1, "original varno: %d varattno: %d", var->varno, var->varattno);
+
+ forboth(lc1, attnomap->attno, lc2, attnomap->attnosyn)
+ {
+ int attno = lfirst_int(lc1);
+ int attnosyn = lfirst_int(lc2);
+
+ elog(DEBUG1, "walker: varattno: %d varattnosyn: %d",attno, attnosyn);
+ if (var->varattno == attnosyn)
+ {
+ elog(DEBUG1, "loc: %d rewrite varattno from: %d to %d", var->location, attnosyn, attno);
+ var->varattno = attno;
+ }
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, (void *) context);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2919,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2970,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3080,7 +3312,7 @@ are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
*
* Returns true if successful, false if no such row
*/
-static bool
+bool
window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
{
WindowAggState *winstate = winobj->winstate;
@@ -3100,7 +3332,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3420,14 +3652,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3494,6 +3766,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
@@ -3565,6 +3843,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3583,15 +3867,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3904,400 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+WindowAggState *
+WinGetAggState(WindowObject winobj)
+{
+ return winobj->winstate;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+
+ /*
+ * Array of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+ #define ENCODED_STR_ARRAY_ALLOC_SIZE 128
+ StringInfo *str_set = NULL;
+ int str_set_index;
+ int str_set_size;
+
+ if (winstate->patternVariableList == NIL)
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ return 0;
+ }
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check whether the row speicied by pos is in the reduced frame. The
+ * second and subsequent rows need to be recognized as "unmatched" rows if
+ * AFTER MATCH SKIP PAST LAST ROW is defined.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ pos > winstate->headpos_in_reduced_frame &&
+ pos < (winstate->headpos_in_reduced_frame + winstate->num_rows_in_reduced_frame))
+ return -2;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ /* build encoded string array */
+ if (str_set == NULL)
+ {
+ str_set_index = 0;
+ str_set_size = ENCODED_STR_ARRAY_ALLOC_SIZE * sizeof(StringInfo);
+ str_set = palloc(str_set_size);
+ }
+
+ str_set[str_set_index++] = encoded_str;
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ if (str_set_index >= str_set_size)
+ {
+ str_set_size *= 2;
+ str_set = repalloc(str_set, str_set_size);
+ }
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (str_set == NULL)
+ {
+ /* no matches found in the first row */
+ return -1;
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ appendStringInfoChar(pattern_str, vname[0]);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s quantifier: %s", vname, quantifier);
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set, str_set_index);
+ if (num_matched_rows <= 0)
+ return -1;
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ winstate->headpos_in_reduced_frame = original_pos;
+ winstate->num_rows_in_reduced_frame = num_matched_rows;
+
+ return num_matched_rows;
+}
+
+/*
+ * search set of encode_str.
+ * set_size: size of set_str array.
+ */
+static
+int search_str_set(char *pattern, StringInfo *str_set, int set_size)
+{
+ char *encoded_str = palloc0(set_size+1);
+ int resultlen = 0;
+
+ search_str_set_recurse(pattern, str_set, set_size, 0, encoded_str, &resultlen);
+ elog(DEBUG1, "search_str_set returns %d", resultlen);
+ return resultlen;
+}
+
+static
+void search_str_set_recurse(char *pattern, StringInfo *str_set, int set_size, int set_index, char *encoded_str, int *resultlen)
+{
+ char *p;
+
+ if (set_index >= set_size)
+ {
+ Datum d;
+ text *res;
+ char *substr;
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how log the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr is, it error
+ * out if pattern is not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ int len;
+
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ if (len > *resultlen)
+ /* remember the longest match */
+ *resultlen = len;
+ }
+ }
+ return;
+ }
+
+ p = str_set[set_index]->data;
+ while (*p)
+ {
+ encoded_str[set_index] = *p;
+ p++;
+ search_str_set_recurse(pattern, str_set, set_size, set_index + 1, encoded_str, resultlen);
+ }
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList)
+ {
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, vname[0]);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ }
+ econtext->ecxt_scantuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_outertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_outertuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_outertuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_outertuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..e4cab36ec9 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,26 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989..fa100b2665 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10397,6 +10397,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..4fd3bd1a93 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2519,6 +2519,14 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2563,16 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /* head of the reduced window frame */
+ int64 headpos_in_reduced_frame;
+ /* number of rows in the reduced window frame */
+ int64 num_rows_in_reduced_frame;
} WindowAggState;
/* ----------------
diff --git a/src/include/windowapi.h b/src/include/windowapi.h
index b8c2c565d1..1e292648e9 100644
--- a/src/include/windowapi.h
+++ b/src/include/windowapi.h
@@ -58,7 +58,15 @@ extern Datum WinGetFuncArgInFrame(WindowObject winobj, int argno,
int relpos, int seektype, bool set_mark,
bool *isnull, bool *isout);
+extern int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+
extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno,
bool *isnull);
+extern WindowAggState *WinGetAggState(WindowObject winobj);
+
+extern bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
#endif /* WINDOWAPI_H */
--
2.25.1
----Next_Part(Wed_Jul_26_21_21_34_2023_317)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v3-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v4 4/7] Row pattern recognition patch (executor).
@ 2023-08-09 07:56 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-08-09 07:56 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 674 ++++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 38 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 19 +
src/include/windowapi.h | 8 +
5 files changed, 732 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..5354e47045 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -182,8 +184,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +198,20 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringInfo *str_set, int set_size);
+static void search_str_set_recurse(char *pattern, StringInfo *str_set, int set_size, int set_index,
+ char *encoded_str, int *resultlen);
+static char pattern_initial(WindowAggState *winstate, char *vname);
/*
* initialize_windowaggregate
@@ -673,6 +687,9 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool reduced_frame_set;
+ bool check_reduced_frame;
+ int num_rows_in_reduced_frame;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -790,6 +807,7 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
winstate->aggregatedupto <= winstate->frameheadpos)
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +879,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -919,6 +939,10 @@ eval_windowaggregates(WindowAggState *winstate)
ExecClearTuple(agg_row_slot);
}
+ reduced_frame_set = false;
+ check_reduced_frame = false;
+ num_rows_in_reduced_frame = 0;
+
/*
* Advance until we reach a row not in frame (or end of partition).
*
@@ -930,12 +954,18 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
if (!window_gettupleslot(agg_winobj, winstate->aggregatedupto,
agg_row_slot))
+ {
+ if (check_reduced_frame)
+ winstate->aggregatedupto--;
break; /* must be end of partition */
+ }
}
/*
@@ -944,10 +974,47 @@ eval_windowaggregates(WindowAggState *winstate)
*/
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
+ {
+ if (winstate->patternVariableList != NIL && check_reduced_frame)
+ winstate->aggregatedupto--;
break;
+ }
if (ret == 0)
goto next_tuple;
+ if (winstate->patternVariableList != NIL)
+ {
+ if (!reduced_frame_set)
+ {
+ num_rows_in_reduced_frame = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ reduced_frame_set = true;
+ elog(DEBUG1, "set num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+
+ if (num_rows_in_reduced_frame <= 0)
+ break;
+
+ else if (num_rows_in_reduced_frame > 0)
+ check_reduced_frame = true;
+ }
+
+ if (check_reduced_frame)
+ {
+ elog(DEBUG1, "decrease num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+ num_rows_in_reduced_frame--;
+ if (num_rows_in_reduced_frame < 0)
+ {
+ /*
+ * No more rows remain in the reduced frame. Finish
+ * accumulating row into the aggregates.
+ */
+ winstate->aggregatedupto--;
+ break;
+ }
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1043,8 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+ elog(DEBUG1, "===== break loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -2053,6 +2122,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2388,6 +2459,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2557,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2751,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2791,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2859,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2910,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3080,7 +3252,7 @@ are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
*
* Returns true if successful, false if no such row
*/
-static bool
+bool
window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
{
WindowAggState *winstate = winobj->winstate;
@@ -3100,7 +3272,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3420,14 +3592,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3494,6 +3706,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
@@ -3565,6 +3783,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3583,15 +3807,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3844,433 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+WindowAggState *
+WinGetAggState(WindowObject winobj)
+{
+ return winobj->winstate;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+
+ /*
+ * Array of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+ #define ENCODED_STR_ARRAY_ALLOC_SIZE 128
+ StringInfo *str_set = NULL;
+ int str_set_index;
+ int str_set_size;
+
+ if (winstate->patternVariableList == NIL)
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ return 0;
+ }
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check whether the row speicied by pos is in the reduced frame. The
+ * second and subsequent rows need to be recognized as "unmatched" rows if
+ * AFTER MATCH SKIP PAST LAST ROW is defined.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ pos > winstate->headpos_in_reduced_frame &&
+ pos < (winstate->headpos_in_reduced_frame + winstate->num_rows_in_reduced_frame))
+ return -2;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ /* build encoded string array */
+ if (str_set == NULL)
+ {
+ str_set_index = 0;
+ str_set_size = ENCODED_STR_ARRAY_ALLOC_SIZE * sizeof(StringInfo);
+ str_set = palloc(str_set_size);
+ }
+
+ str_set[str_set_index++] = encoded_str;
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ if (str_set_index >= str_set_size)
+ {
+ str_set_size *= 2;
+ str_set = repalloc(str_set, str_set_size);
+ }
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (str_set == NULL)
+ {
+ /* no matches found in the first row */
+ return -1;
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s initial: %c quantifier: %s", vname, initial, quantifier);
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set, str_set_index);
+ if (num_matched_rows <= 0)
+ return -1;
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ winstate->headpos_in_reduced_frame = original_pos;
+ winstate->num_rows_in_reduced_frame = num_matched_rows;
+
+ return num_matched_rows;
+}
+
+/*
+ * search set of encode_str.
+ * set_size: size of set_str array.
+ */
+static
+int search_str_set(char *pattern, StringInfo *str_set, int set_size)
+{
+ char *encoded_str = palloc0(set_size+1);
+ int resultlen = 0;
+
+ search_str_set_recurse(pattern, str_set, set_size, 0, encoded_str, &resultlen);
+ elog(DEBUG1, "search_str_set returns %d", resultlen);
+ return resultlen;
+}
+
+static
+void search_str_set_recurse(char *pattern, StringInfo *str_set,
+ int set_size, int set_index, char *encoded_str, int *resultlen)
+{
+ char *p;
+
+ if (set_index >= set_size)
+ {
+ Datum d;
+ text *res;
+ char *substr;
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how log the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr is, it error
+ * out if pattern is not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ int len;
+
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ if (len > *resultlen)
+ /* remember the longest match */
+ *resultlen = len;
+ }
+ }
+ return;
+ }
+
+ p = str_set[set_index]->data;
+ while (*p)
+ {
+ encoded_str[set_index] = *p;
+ p++;
+ search_str_set_recurse(pattern, str_set, set_size, set_index + 1, encoded_str, resultlen);
+ }
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ elog(DEBUG1, "evaluate_pattern: define variable: %s, pattern variable: %s", name, vname);
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..e4cab36ec9 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,26 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989..fa100b2665 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10397,6 +10397,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..2bd6fcb5e1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2519,6 +2519,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2564,16 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /* head of the reduced window frame */
+ int64 headpos_in_reduced_frame;
+ /* number of rows in the reduced window frame */
+ int64 num_rows_in_reduced_frame;
} WindowAggState;
/* ----------------
diff --git a/src/include/windowapi.h b/src/include/windowapi.h
index b8c2c565d1..1e292648e9 100644
--- a/src/include/windowapi.h
+++ b/src/include/windowapi.h
@@ -58,7 +58,15 @@ extern Datum WinGetFuncArgInFrame(WindowObject winobj, int argno,
int relpos, int seektype, bool set_mark,
bool *isnull, bool *isout);
+extern int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+
extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno,
bool *isnull);
+extern WindowAggState *WinGetAggState(WindowObject winobj);
+
+extern bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
#endif /* WINDOWAPI_H */
--
2.25.1
----Next_Part(Wed_Aug__9_17_41_12_2023_134)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v4-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v5 4/7] Row pattern recognition patch (executor).
@ 2023-09-02 06:32 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-09-02 06:32 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 671 ++++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 38 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 19 +
4 files changed, 722 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..2e59369a71 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -182,8 +184,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +198,25 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringInfo *str_set, int set_size);
+static void search_str_set_recurse(char *pattern, StringInfo *str_set, int set_size, int set_index,
+ char *encoded_str, int *resultlen);
+static char pattern_initial(WindowAggState *winstate, char *vname);
/*
* initialize_windowaggregate
@@ -673,6 +692,9 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool reduced_frame_set;
+ bool check_reduced_frame;
+ int num_rows_in_reduced_frame;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -790,6 +812,7 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
winstate->aggregatedupto <= winstate->frameheadpos)
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +884,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -919,6 +944,10 @@ eval_windowaggregates(WindowAggState *winstate)
ExecClearTuple(agg_row_slot);
}
+ reduced_frame_set = false;
+ check_reduced_frame = false;
+ num_rows_in_reduced_frame = 0;
+
/*
* Advance until we reach a row not in frame (or end of partition).
*
@@ -930,12 +959,18 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
if (!window_gettupleslot(agg_winobj, winstate->aggregatedupto,
agg_row_slot))
+ {
+ if (check_reduced_frame)
+ winstate->aggregatedupto--;
break; /* must be end of partition */
+ }
}
/*
@@ -944,10 +979,47 @@ eval_windowaggregates(WindowAggState *winstate)
*/
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
+ {
+ if (winstate->patternVariableList != NIL && check_reduced_frame)
+ winstate->aggregatedupto--;
break;
+ }
if (ret == 0)
goto next_tuple;
+ if (winstate->patternVariableList != NIL)
+ {
+ if (!reduced_frame_set)
+ {
+ num_rows_in_reduced_frame = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ reduced_frame_set = true;
+ elog(DEBUG1, "set num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+
+ if (num_rows_in_reduced_frame <= 0)
+ break;
+
+ else if (num_rows_in_reduced_frame > 0)
+ check_reduced_frame = true;
+ }
+
+ if (check_reduced_frame)
+ {
+ elog(DEBUG1, "decrease num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+ num_rows_in_reduced_frame--;
+ if (num_rows_in_reduced_frame < 0)
+ {
+ /*
+ * No more rows remain in the reduced frame. Finish
+ * accumulating row into the aggregates.
+ */
+ winstate->aggregatedupto--;
+ break;
+ }
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1048,8 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+ elog(DEBUG1, "===== break loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -2053,6 +2127,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2388,6 +2464,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2562,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2756,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2796,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2864,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2915,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3100,7 +3277,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3420,14 +3597,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3494,6 +3711,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
@@ -3565,6 +3788,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3583,15 +3812,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3849,427 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+
+ /*
+ * Array of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+ #define ENCODED_STR_ARRAY_ALLOC_SIZE 128
+ StringInfo *str_set = NULL;
+ int str_set_index;
+ int str_set_size;
+
+ if (winstate->patternVariableList == NIL)
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ return 0;
+ }
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check whether the row speicied by pos is in the reduced frame. The
+ * second and subsequent rows need to be recognized as "unmatched" rows if
+ * AFTER MATCH SKIP PAST LAST ROW is defined.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ pos > winstate->headpos_in_reduced_frame &&
+ pos < (winstate->headpos_in_reduced_frame + winstate->num_rows_in_reduced_frame))
+ return -2;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ /* build encoded string array */
+ if (str_set == NULL)
+ {
+ str_set_index = 0;
+ str_set_size = ENCODED_STR_ARRAY_ALLOC_SIZE * sizeof(StringInfo);
+ str_set = palloc(str_set_size);
+ }
+
+ str_set[str_set_index++] = encoded_str;
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ if (str_set_index >= str_set_size)
+ {
+ str_set_size *= 2;
+ str_set = repalloc(str_set, str_set_size);
+ }
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (str_set == NULL)
+ {
+ /* no matches found in the first row */
+ return -1;
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s initial: %c quantifier: %s", vname, initial, quantifier);
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set, str_set_index);
+ if (num_matched_rows <= 0)
+ return -1;
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ winstate->headpos_in_reduced_frame = original_pos;
+ winstate->num_rows_in_reduced_frame = num_matched_rows;
+
+ return num_matched_rows;
+}
+
+/*
+ * search set of encode_str.
+ * set_size: size of set_str array.
+ */
+static
+int search_str_set(char *pattern, StringInfo *str_set, int set_size)
+{
+ char *encoded_str = palloc0(set_size+1);
+ int resultlen = 0;
+
+ search_str_set_recurse(pattern, str_set, set_size, 0, encoded_str, &resultlen);
+ elog(DEBUG1, "search_str_set returns %d", resultlen);
+ return resultlen;
+}
+
+static
+void search_str_set_recurse(char *pattern, StringInfo *str_set,
+ int set_size, int set_index, char *encoded_str, int *resultlen)
+{
+ char *p;
+
+ if (set_index >= set_size)
+ {
+ Datum d;
+ text *res;
+ char *substr;
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how log the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr is, it error
+ * out if pattern is not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ int len;
+
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ if (len > *resultlen)
+ /* remember the longest match */
+ *resultlen = len;
+ }
+ }
+ return;
+ }
+
+ p = str_set[set_index]->data;
+ while (*p)
+ {
+ encoded_str[set_index] = *p;
+ p++;
+ search_str_set_recurse(pattern, str_set, set_size, set_index + 1, encoded_str, resultlen);
+ }
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ elog(DEBUG1, "evaluate_pattern: define variable: %s, pattern variable: %s", name, vname);
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..e4cab36ec9 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,26 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 9805bc6118..d20f803cf5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10416,6 +10416,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..2bd6fcb5e1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2519,6 +2519,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2564,16 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /* head of the reduced window frame */
+ int64 headpos_in_reduced_frame;
+ /* number of rows in the reduced window frame */
+ int64 num_rows_in_reduced_frame;
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Sat_Sep__2_15_52_35_2023_273)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v5-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v6 4/7] Row pattern recognition patch (executor).
@ 2023-09-12 05:22 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-09-12 05:22 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 842 ++++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 898 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..32270d051a 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -182,8 +184,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +198,32 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringInfo *str_set, int set_size);
+static void search_str_set_recurse(char *pattern, StringInfo *str_set, int set_size, int set_index,
+ char *encoded_str, int *resultlen);
+static char pattern_initial(WindowAggState *winstate, char *vname);
/*
* initialize_windowaggregate
@@ -673,6 +699,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +805,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +818,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +894,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -917,6 +952,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row or an unmatched row, we don't need to
+ * accumulate rows, just return NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ (get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED ||
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_UNMATCHED))
+ agg_result_isnull = true;
}
/*
@@ -930,6 +988,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1008,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1058,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1079,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is enabled and we just return NULL. because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row or unmatched row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1183,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2147,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2317,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2495,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2593,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2787,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2827,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2895,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2946,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3100,7 +3308,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3420,14 +3628,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3494,11 +3742,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3565,6 +3823,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3583,15 +3847,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3884,561 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+
+ /*
+ * Array of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+ #define ENCODED_STR_ARRAY_ALLOC_SIZE 128
+ StringInfo *str_set = NULL;
+ int str_set_index;
+ int str_set_size;
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ /* build encoded string array */
+ if (str_set == NULL)
+ {
+ str_set_index = 0;
+ str_set_size = ENCODED_STR_ARRAY_ALLOC_SIZE * sizeof(StringInfo);
+ str_set = palloc(str_set_size);
+ }
+
+ str_set[str_set_index++] = encoded_str;
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ if (str_set_index >= str_set_size)
+ {
+ str_set_size *= 2;
+ str_set = repalloc(str_set, str_set_size);
+ }
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (str_set == NULL)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s initial: %c quantifier: %s", vname, initial, quantifier);
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set, str_set_index);
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ int64 i;
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search set of encode_str.
+ * set_size: size of set_str array.
+ */
+static
+int search_str_set(char *pattern, StringInfo *str_set, int set_size)
+{
+ char *encoded_str = palloc0(set_size+1);
+ int resultlen = 0;
+
+ search_str_set_recurse(pattern, str_set, set_size, 0, encoded_str, &resultlen);
+ elog(DEBUG1, "search_str_set returns %d", resultlen);
+ return resultlen;
+}
+
+/*
+ * Workhorse of search_str_set.
+ */
+static
+void search_str_set_recurse(char *pattern, StringInfo *str_set,
+ int set_size, int set_index, char *encoded_str, int *resultlen)
+{
+ char *p;
+
+ if (set_index >= set_size)
+ {
+ Datum d;
+ text *res;
+ char *substr;
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how log the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr is, it error
+ * out if pattern is not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ int len;
+
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ if (len > *resultlen)
+ /* remember the longest match */
+ *resultlen = len;
+ }
+ }
+ return;
+ }
+
+ p = str_set[set_index]->data;
+ while (*p)
+ {
+ encoded_str[set_index] = *p;
+ p++;
+ search_str_set_recurse(pattern, str_set, set_size, set_index + 1, encoded_str, resultlen);
+ }
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..9ebcc7b5d2 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 9805bc6118..d20f803cf5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10416,6 +10416,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..63feb68f60 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2471,6 +2471,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2519,6 +2524,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2569,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Tue_Sep_12_15_18_43_2023_359)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v6-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v7 4/7] Row pattern recognition patch (executor).
@ 2023-09-22 04:53 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-09-22 04:53 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 853 ++++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 909 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..84d1b8acaa 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -182,8 +184,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +198,32 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringInfo *str_set, int set_size);
+static void search_str_set_recurse(char *pattern, StringInfo *str_set, int set_size, int set_index,
+ int str_index, char *encoded_str, int *resultlen);
+static char pattern_initial(WindowAggState *winstate, char *vname);
/*
* initialize_windowaggregate
@@ -673,6 +699,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +805,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +818,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +894,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -917,6 +952,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +988,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1008,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1058,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1079,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1183,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2147,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2317,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2495,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2593,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2787,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2827,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2895,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2946,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3100,7 +3308,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3420,14 +3628,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3494,11 +3742,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3565,6 +3823,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3583,15 +3847,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3884,572 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+
+ /*
+ * Array of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+ #define ENCODED_STR_ARRAY_ALLOC_SIZE 128
+ StringInfo *str_set = NULL;
+ int str_set_index;
+ int str_set_size;
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ /* build encoded string array */
+ if (str_set == NULL)
+ {
+ str_set_index = 0;
+ str_set_size = ENCODED_STR_ARRAY_ALLOC_SIZE * sizeof(StringInfo);
+ str_set = palloc(str_set_size);
+ }
+
+ str_set[str_set_index++] = encoded_str;
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ if (str_set_index >= str_set_size)
+ {
+ str_set_size *= 2;
+ str_set = repalloc(str_set, str_set_size);
+ }
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (str_set == NULL)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s initial: %c quantifier: %s", vname, initial, quantifier);
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set, str_set_index);
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ int64 i;
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * Perform regex search pattern against encoded string array str_set.
+ * returns the number of longest matching rows.
+ * str_set: array of encoded string. Each array element corresponds to each
+ * row.
+ * set_size: size of set_str array.
+ */
+static
+int search_str_set(char *pattern, StringInfo *str_set, int set_size)
+{
+ char *encoded_str = palloc0(set_size+1);
+ int resultlen = 0;
+
+ search_str_set_recurse(pattern, str_set, set_size, 0, 0,
+ encoded_str, &resultlen);
+ elog(DEBUG1, "search_str_set returns %d", resultlen);
+ return resultlen;
+}
+
+/*
+ * Workhorse of search_str_set.
+ *
+ * Recurse among matched pattern variables in a row. The max recursion depth
+ * is number of pattern variables matched in a row.
+ */
+static
+void search_str_set_recurse(char *pattern, StringInfo *str_set,
+ int set_size, int set_index, int str_index,
+ char *encoded_str, int *resultlen)
+{
+ for (;;)
+ {
+ char c;
+
+ c = str_set[set_index]->data[str_index];
+ if (c == '\0')
+ return;
+ encoded_str[set_index] = c;
+ set_index++;
+
+ if (set_index >= set_size)
+ {
+ Datum d;
+ text *res;
+ char *substr;
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr in the first
+ * place is, it errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ int len;
+
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ if (len > *resultlen)
+ /* remember the longest match */
+ *resultlen = len;
+ }
+ }
+ return;
+ }
+ else
+ search_str_set_recurse(pattern, str_set, set_size, set_index, str_index + 1,
+ encoded_str, resultlen);
+ }
+}
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..9ebcc7b5d2 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 9805bc6118..d20f803cf5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10416,6 +10416,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..63feb68f60 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2471,6 +2471,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2519,6 +2524,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2569,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Fri_Sep_22_14_16_40_2023_530)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v7-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v8 4/7] Row pattern recognition patch (executor).
@ 2023-09-25 05:01 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-09-25 05:01 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1024 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 1080 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..5f2dfdf943 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,12 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+typedef struct StringSet {
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of items */
+ int set_index; /* current used size */
+} StringSet;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -182,8 +190,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +204,37 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet *str_set);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet *string_set_init(void);
+static void string_set_add(StringSet *string_set, StringInfo str);
+static StringInfo string_set_get(StringSet *string_set, int index);
+static int string_set_get_size(StringSet *string_set);
+static void string_set_discard(StringSet *string_set);
/*
* initialize_windowaggregate
@@ -673,6 +710,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +816,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +829,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +905,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -917,6 +963,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +999,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1019,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1069,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1090,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1194,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2158,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2328,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2506,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2604,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2798,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2838,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2906,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2957,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3100,7 +3319,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3420,14 +3639,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3494,11 +3753,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3565,6 +3834,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3583,15 +3858,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3895,732 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int str_set_index = 0;
+
+ /*
+ * Set of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s initial: %c quantifier: %s", vname, initial, quantifier);
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set);
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ int64 i;
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * Perform pattern matching using pattern against str_set. str_set is a set
+ * of StringInfo. Each StringInfo has a string comprising initial characters
+ * of pattern variables being true in a row. Returns the longest number of
+ * the matching rows.
+ */
+static
+int search_str_set(char *pattern, StringSet *str_set)
+{
+ int set_size; /* number of rows in the set */
+ int resultlen = 0;
+ int index;
+ StringSet *old_str_set, *new_str_set;
+ int new_str_size;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * loop over each new pattern variable char in previous result
+ * char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ p++; /* next pattern variable */
+ }
+ }
+ else
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size ; i++)
+ {
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = str->data;
+
+ /*
+ * loop over each pattern variable char in the input set.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* copy source string */
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ p++; /* next pattern variable */
+ }
+ }
+ /* we no long need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ int len;
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no long need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr in the first
+ * place is, it errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ }
+ }
+ return len;
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet *string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void string_set_add(StringSet *string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo string_set_get(StringSet *string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 ||index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * Returns the size of StringSet.
+ */
+static
+int string_set_get_size(StringSet *string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void string_set_discard(StringSet *string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+ pfree(str->data);
+ pfree(str);
+ }
+ pfree(string_set);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..9ebcc7b5d2 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 9805bc6118..d20f803cf5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10416,6 +10416,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..63feb68f60 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2471,6 +2471,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2519,6 +2524,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2569,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Mon_Sep_25_14_26_30_2023_752)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v8-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v9 4/7] Row pattern recognition patch (executor).
@ 2023-10-04 05:51 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-10-04 05:51 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1021 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 1077 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 77724a6daa..5da1bb5a6f 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,12 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+typedef struct StringSet {
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of items */
+ int set_index; /* current used size */
+} StringSet;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -182,8 +190,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +204,37 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet *str_set);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet *string_set_init(void);
+static void string_set_add(StringSet *string_set, StringInfo str);
+static StringInfo string_set_get(StringSet *string_set, int index);
+static int string_set_get_size(StringSet *string_set);
+static void string_set_discard(StringSet *string_set);
/*
* initialize_windowaggregate
@@ -673,6 +710,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +816,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +829,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +905,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -917,6 +963,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +999,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1019,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1069,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1090,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1194,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2158,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2328,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2506,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2604,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2798,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2838,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +2938,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3300,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3620,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3734,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3815,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3839,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3876,731 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int str_set_index = 0;
+
+ /*
+ * Set of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s initial: %c quantifier: %s", vname, initial, quantifier);
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set);
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ int64 i;
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * Perform pattern matching using pattern against str_set. str_set is a set
+ * of StringInfo. Each StringInfo has a string comprising initial characters
+ * of pattern variables being true in a row. Returns the longest number of
+ * the matching rows.
+ */
+static
+int search_str_set(char *pattern, StringSet *str_set)
+{
+ int set_size; /* number of rows in the set */
+ int resultlen = 0;
+ int index;
+ StringSet *old_str_set, *new_str_set;
+ int new_str_size;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * loop over each new pattern variable char in previous result
+ * char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ p++; /* next pattern variable */
+ }
+ }
+ else
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size ; i++)
+ {
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = str->data;
+
+ /*
+ * loop over each pattern variable char in the input set.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* copy source string */
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ p++; /* next pattern variable */
+ }
+ }
+ /* we no long need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ int len;
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no long need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr in the first
+ * place is, it errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ }
+ }
+ return len;
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet *string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void string_set_add(StringSet *string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo string_set_get(StringSet *string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 ||index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * Returns the size of StringSet.
+ */
+static
+int string_set_get_size(StringSet *string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void string_set_discard(StringSet *string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+ pfree(str->data);
+ pfree(str);
+ }
+ pfree(string_set);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..9ebcc7b5d2 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index f0b7b9cbd8..24d288336a 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10416,6 +10416,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 108d69ba28..28d098b1cf 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2470,6 +2470,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2518,6 +2523,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2554,6 +2568,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Wed_Oct__4_15_03_28_2023_821)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v9-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v10 4/7] Row pattern recognition patch (executor).
@ 2023-10-22 02:22 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-10-22 02:22 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1363 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 1419 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 77724a6daa..2e1baef7ea 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,40 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet {
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos {
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -182,8 +218,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +232,43 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+//static int search_str_set(char *pattern, StringSet *str_set, int *initial_orders);
+static int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet *string_set_init(void);
+static void string_set_add(StringSet *string_set, StringInfo str);
+static StringInfo string_set_get(StringSet *string_set, int index);
+static int string_set_get_size(StringSet *string_set);
+static void string_set_discard(StringSet *string_set);
+static VariablePos *variable_pos_init(void);
+static void variable_pos_register(VariablePos *variable_pos, char initial, int pos);
+static bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2);
+static int variable_pos_fetch(VariablePos *variable_pos, char initial, int index);
+static void variable_pos_discard(VariablePos *variable_pos);
/*
* initialize_windowaggregate
@@ -673,6 +744,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +850,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +863,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +939,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -917,6 +997,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +1033,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1053,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1103,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1124,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1228,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2192,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2362,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2540,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2638,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2832,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2872,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +2972,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3334,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3654,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3768,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3849,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3873,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3910,1039 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int str_set_index = 0;
+ int initial_index;
+ VariablePos *variable_pos;
+
+ /*
+ * Set of pattern variables evaluated to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ elog(DEBUG1, "search_str_set started");
+ num_matched_rows = search_str_set(pattern_str->data, str_set, variable_pos);
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ int64 i;
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * Perform pattern matching using pattern against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. For example, if DEFINE has variables START, UP and
+ * DOWN, PATTERN HAS START, UP and DOWN, then the initials in PATTERN will be
+ * 'a', 'b' and 'c'.
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows.
+ */
+static
+int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set, *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+ elog(DEBUG1, "index: %d", index);
+
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size ; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+ elog(DEBUG1, "discard this old set because shorter match: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "keep this old set: %s", old->data);
+ new = makeStringInfo();
+ appendStringInfoString(new, old->data);
+ string_set_add(new_str_set, new);
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+ elog(DEBUG1, "discard this old set: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "str->data: %s", str->data);
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed
+ * entries that have shorter match length.
+ * Mark them as "discard" so that they are
+ * discarded in the next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size = string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size; new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char = new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /* mark this set to discard in the next round */
+ appendStringInfoChar(new, DISCARD_CHAR);
+ elog(DEBUG1, "add discard char: %s", new->data);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+ elog(DEBUG1, "target string: %s", s->data);
+
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text, *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr in the first
+ * place is, it errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet *string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void string_set_add(StringSet *string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo string_set_get(StringSet *string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 ||index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * Returns the size of StringSet.
+ */
+static
+int string_set_get_size(StringSet *string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void string_set_discard(StringSet *string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+ pfree(str->data);
+ pfree(str);
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos *variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void variable_pos_register(VariablePos *variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2)
+{
+ int index1, index2;
+ int pos1, pos2;
+
+ for (index1 = 0; ; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0; ; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int variable_pos_fetch(VariablePos *variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * Discard VariablePos
+ */
+static
+void variable_pos_discard(VariablePos *variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..9ebcc7b5d2 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index c92d0631a0..ebb017b015 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10425,6 +10425,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 108d69ba28..28d098b1cf 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2470,6 +2470,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2518,6 +2523,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2554,6 +2568,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Sun_Oct_22_11_39_20_2023_140)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v10-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v11 4/7] Row pattern recognition patch (executor).
@ 2023-11-08 06:57 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-11-08 06:57 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1420 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 1476 insertions(+), 13 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 77724a6daa..ea5e73c969 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,40 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet {
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos {
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -182,8 +218,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +232,42 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet *string_set_init(void);
+static void string_set_add(StringSet *string_set, StringInfo str);
+static StringInfo string_set_get(StringSet *string_set, int index);
+static int string_set_get_size(StringSet *string_set);
+static void string_set_discard(StringSet *string_set);
+static VariablePos *variable_pos_init(void);
+static void variable_pos_register(VariablePos *variable_pos, char initial, int pos);
+static bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2);
+static int variable_pos_fetch(VariablePos *variable_pos, char initial, int index);
+static void variable_pos_discard(VariablePos *variable_pos);
/*
* initialize_windowaggregate
@@ -673,6 +743,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +849,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +862,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +938,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -917,6 +996,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +1032,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1052,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1102,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1123,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1227,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2191,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2361,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2539,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2637,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2831,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2871,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +2971,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3333,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3653,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3767,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3848,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3872,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3909,1097 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int str_set_index = 0;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos, i;
+
+ /*
+ * Set of pattern variables evaluated to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier.
+ * If it does not, we can just apply the pattern to each row.
+ * If it succeeds, we are done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s", pos, vname);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+ elog(DEBUG1, "expression result is false or out of frame");
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+ elog(DEBUG1, "pattern matched");
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included.
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ elog(DEBUG1, "search_str_set started");
+ num_matched_rows = search_str_set(pattern_str->data, str_set, variable_pos);
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * Perform pattern matching using pattern against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. For example, if DEFINE has variables START, UP and
+ * DOWN, PATTERN HAS START, UP and DOWN, then the initials in PATTERN will be
+ * 'a', 'b' and 'c'.
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows.
+ */
+static
+int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set, *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+ elog(DEBUG1, "index: %d", index);
+
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size ; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+ elog(DEBUG1, "discard this old set because shorter match: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "keep this old set: %s", old->data);
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+ elog(DEBUG1, "discard this old set: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "str->data: %s", str->data);
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed
+ * entries that have shorter match length.
+ * Mark them as "discard" so that they are
+ * discarded in the next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size = string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size; new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char = new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /* mark this set to discard in the next round */
+ appendStringInfoChar(new, DISCARD_CHAR);
+ elog(DEBUG1, "add discard char: %s", new->data);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+ elog(DEBUG1, "target string: %s", s->data);
+
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text, *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr in the first
+ * place is, it errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet *string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void string_set_add(StringSet *string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo string_set_get(StringSet *string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 ||index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * Returns the size of StringSet.
+ */
+static
+int string_set_get_size(StringSet *string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void string_set_discard(StringSet *string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos *variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void variable_pos_register(VariablePos *variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2)
+{
+ int index1, index2;
+ int pos1, pos2;
+
+ for (index1 = 0; ; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0; ; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int variable_pos_fetch(VariablePos *variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * Discard VariablePos
+ */
+static
+void variable_pos_discard(VariablePos *variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 0bfbac00d7..a4a11c7f8d 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index f14aed422a..6df54a3cab 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10423,6 +10423,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5d7f17dee0..d8f92720bc 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2470,6 +2470,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2518,6 +2523,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2554,6 +2568,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Wed_Nov__8_16_37_05_2023_872)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v11-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v12 4/7] Row pattern recognition patch (executor).
@ 2023-12-04 11:23 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2023-12-04 11:23 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1435 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 1490 insertions(+), 14 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3258305f57..a093e5dec6 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,40 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet {
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos {
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -182,8 +218,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +232,42 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet *string_set_init(void);
+static void string_set_add(StringSet *string_set, StringInfo str);
+static StringInfo string_set_get(StringSet *string_set, int index);
+static int string_set_get_size(StringSet *string_set);
+static void string_set_discard(StringSet *string_set);
+static VariablePos *variable_pos_init(void);
+static void variable_pos_register(VariablePos *variable_pos, char initial, int pos);
+static bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2);
+static int variable_pos_fetch(VariablePos *variable_pos, char initial, int index);
+static void variable_pos_discard(VariablePos *variable_pos);
/*
* initialize_windowaggregate
@@ -673,6 +743,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +849,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +862,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -862,7 +939,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1009,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +1045,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1065,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1115,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1136,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1240,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2204,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2374,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2552,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2650,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2844,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2884,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +2984,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3346,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3666,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3780,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3861,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3885,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3922,1097 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int str_set_index = 0;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos, i;
+
+ /*
+ * Set of pattern variables evaluated to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier.
+ * If it does not, we can just apply the pattern to each row.
+ * If it succeeds, we are done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s", pos, vname);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+ elog(DEBUG1, "expression result is false or out of frame");
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+ elog(DEBUG1, "pattern matched");
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included.
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ elog(DEBUG1, "search_str_set started");
+ num_matched_rows = search_str_set(pattern_str->data, str_set, variable_pos);
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * Perform pattern matching using pattern against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. For example, if DEFINE has variables START, UP and
+ * DOWN, PATTERN HAS START, UP and DOWN, then the initials in PATTERN will be
+ * 'a', 'b' and 'c'.
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows.
+ */
+static
+int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set, *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+ elog(DEBUG1, "index: %d", index);
+
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size ; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+ elog(DEBUG1, "discard this old set because shorter match: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "keep this old set: %s", old->data);
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+ elog(DEBUG1, "discard this old set: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "str->data: %s", str->data);
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed
+ * entries that have shorter match length.
+ * Mark them as "discard" so that they are
+ * discarded in the next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size = string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size; new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char = new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /* mark this set to discard in the next round */
+ appendStringInfoChar(new, DISCARD_CHAR);
+ elog(DEBUG1, "add discard char: %s", new->data);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+ elog(DEBUG1, "target string: %s", s->data);
+
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text, *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr in the first
+ * place is, it errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet *string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void string_set_add(StringSet *string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo string_set_get(StringSet *string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 ||index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * Returns the size of StringSet.
+ */
+static
+int string_set_get_size(StringSet *string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void string_set_discard(StringSet *string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos *variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void variable_pos_register(VariablePos *variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2)
+{
+ int index1, index2;
+ int pos1, pos2;
+
+ for (index1 = 0; ; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0; ; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int variable_pos_fetch(VariablePos *variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * Discard VariablePos
+ */
+static
+void variable_pos_discard(VariablePos *variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 0bfbac00d7..a4a11c7f8d 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index fb58dee3bc..aec365cf07 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10437,6 +10437,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5d7f17dee0..d8f92720bc 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2470,6 +2470,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2518,6 +2523,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2554,6 +2568,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Fri_Dec__8_10_16_13_2023_489)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v12-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
@ 2024-01-17 21:01 ` Alexander Korotkov <[email protected]>
1 sibling, 0 replies; 94+ messages in thread
From: Alexander Korotkov @ 2024-01-17 21:01 UTC (permalink / raw)
To: torikoshia <[email protected]>; +Cc: Masahiko Sawada <[email protected]>; jian he <[email protected]>; vignesh C <[email protected]>; Alena Rybakina <[email protected]>; Damir Belyalov <[email protected]>; [email protected]; Tom Lane <[email protected]>; Daniel Gustafsson <[email protected]>; pgsql-hackers; Andres Freund <[email protected]>; [email protected]; [email protected]; [email protected]; Andrei Lepikhov <[email protected]>
On Wed, Jan 17, 2024 at 7:38 AM torikoshia <[email protected]> wrote:
>
> Hi,
>
> Thanks for applying!
>
> > + errmsg_plural("%zd row were skipped due
> > to data type incompatibility",
>
> Sorry, I just noticed it, but 'were' should be 'was' here?
Sure, the fix is pushed.
------
Regards,
Alexander Korotkov
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
@ 2024-01-17 21:06 ` Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
1 sibling, 1 reply; 94+ messages in thread
From: Alexander Korotkov @ 2024-01-17 21:06 UTC (permalink / raw)
To: Kyotaro Horiguchi <[email protected]>; +Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On Wed, Jan 17, 2024 at 9:49 AM Kyotaro Horiguchi
<[email protected]> wrote:
> At Wed, 17 Jan 2024 14:38:54 +0900, torikoshia <[email protected]> wrote in
> > Hi,
> >
> > Thanks for applying!
> >
> > > + errmsg_plural("%zd row were skipped due to data type
> > > incompatibility",
> >
> > Sorry, I just noticed it, but 'were' should be 'was' here?
> >
> > >> BTW I'm thinking we should add a column to pg_stat_progress_copy that
> > >> counts soft errors. I'll suggest this in another thread.
> > > Please do!
> >
> > I've started it here:
> >
> > https://www.postgresql.org/message-id/[email protected]
>
> Switching topics, this commit (9e2d870119) adds the following help message:
>
>
> > "COPY { %s [ ( %s [, ...] ) ] | ( %s ) }\n"
> > " TO { '%s' | PROGRAM '%s' | STDOUT }\n"
> > ...
> > " SAVE_ERROR_TO '%s'\n"
> > ...
> > _("location"),
>
> On the other hand, SAVE_ERROR_TO takes 'error' or 'none', which
> indicate "immediately error out" and 'just ignore the failure'
> respectively, but these options hardly seem to denote a 'location',
> and appear more like an 'action'. I somewhat suspect that this
> parameter name intially conceived with the assupmtion that it would
> take file names or similar parameters. I'm not sure if others will
> agree, but I think the parameter name might not be the best
> choice. For instance, considering the addition of the third value
> 'log', something like on_error_action (error, ignore, log) would be
> more intuitively understandable. What do you think?
Probably, but I'm not sure about that. The name SAVE_ERROR_TO assumes
the next word will be location, not action. With some stretch we can
assume 'error' to be location. I think it would be even more stretchy
to think that SAVE_ERROR_TO is followed by action. Probably, we can
replace SAVE_ERROR_TO with another name which could be naturally
followed by action, but I don't have something appropriate in mind.
However, I'm not native english speaker and certainly could miss
something.
------
Regards,
Alexander Korotkov
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
@ 2024-01-17 21:37 ` Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Tom Lane @ 2024-01-17 21:37 UTC (permalink / raw)
To: Alexander Korotkov <[email protected]>; +Cc: Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Alexander Korotkov <[email protected]> writes:
> On Wed, Jan 17, 2024 at 9:49 AM Kyotaro Horiguchi
> <[email protected]> wrote:
>> On the other hand, SAVE_ERROR_TO takes 'error' or 'none', which
>> indicate "immediately error out" and 'just ignore the failure'
>> respectively, but these options hardly seem to denote a 'location',
>> and appear more like an 'action'. I somewhat suspect that this
>> parameter name intially conceived with the assupmtion that it would
>> take file names or similar parameters. I'm not sure if others will
>> agree, but I think the parameter name might not be the best
>> choice. For instance, considering the addition of the third value
>> 'log', something like on_error_action (error, ignore, log) would be
>> more intuitively understandable. What do you think?
> Probably, but I'm not sure about that. The name SAVE_ERROR_TO assumes
> the next word will be location, not action. With some stretch we can
> assume 'error' to be location. I think it would be even more stretchy
> to think that SAVE_ERROR_TO is followed by action.
The other problem with this terminology is that with 'none', what it
is doing is the exact opposite of "saving" the errors. I agree we
need a better name.
Kyotaro-san's suggestion isn't bad, though I might shorten it to
error_action {error|ignore|log} (or perhaps "stop" instead of "error")?
You will need a separate parameter anyway to specify the destination
of "log", unless "none" became an illegal table name when I wasn't
looking. I don't buy that one parameter that has some special values
while other values could be names will be a good design. Moreover,
what if we want to support (say) log-to-file along with log-to-table?
Trying to distinguish a file name from a table name without any other
context seems impossible.
regards, tom lane
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
@ 2024-01-18 00:56 ` Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Masahiko Sawada @ 2024-01-18 00:56 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Alexander Korotkov <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On Thu, Jan 18, 2024 at 6:38 AM Tom Lane <[email protected]> wrote:
>
> Alexander Korotkov <[email protected]> writes:
> > On Wed, Jan 17, 2024 at 9:49 AM Kyotaro Horiguchi
> > <[email protected]> wrote:
> >> On the other hand, SAVE_ERROR_TO takes 'error' or 'none', which
> >> indicate "immediately error out" and 'just ignore the failure'
> >> respectively, but these options hardly seem to denote a 'location',
> >> and appear more like an 'action'. I somewhat suspect that this
> >> parameter name intially conceived with the assupmtion that it would
> >> take file names or similar parameters. I'm not sure if others will
> >> agree, but I think the parameter name might not be the best
> >> choice. For instance, considering the addition of the third value
> >> 'log', something like on_error_action (error, ignore, log) would be
> >> more intuitively understandable. What do you think?
>
> > Probably, but I'm not sure about that. The name SAVE_ERROR_TO assumes
> > the next word will be location, not action. With some stretch we can
> > assume 'error' to be location. I think it would be even more stretchy
> > to think that SAVE_ERROR_TO is followed by action.
>
> The other problem with this terminology is that with 'none', what it
> is doing is the exact opposite of "saving" the errors. I agree we
> need a better name.
Agreed.
>
> Kyotaro-san's suggestion isn't bad, though I might shorten it to
> error_action {error|ignore|log} (or perhaps "stop" instead of "error")?
> You will need a separate parameter anyway to specify the destination
> of "log", unless "none" became an illegal table name when I wasn't
> looking. I don't buy that one parameter that has some special values
> while other values could be names will be a good design. Moreover,
> what if we want to support (say) log-to-file along with log-to-table?
> Trying to distinguish a file name from a table name without any other
> context seems impossible.
I've been thinking we can add more values to this option to log errors
not only to the server logs but also to the error table (not sure
details but I imagined an error table is created for each table on
error), without an additional option for the destination name. The
values would be like error_action {error|ignore|save-logs|save-table}.
Regards,
--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
@ 2024-01-18 01:10 ` jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: jian he @ 2024-01-18 01:10 UTC (permalink / raw)
To: Masahiko Sawada <[email protected]>; +Cc: Tom Lane <[email protected]>; Alexander Korotkov <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On Thu, Jan 18, 2024 at 8:57 AM Masahiko Sawada <[email protected]> wrote:
>
> On Thu, Jan 18, 2024 at 6:38 AM Tom Lane <[email protected]> wrote:
> >
> > Alexander Korotkov <[email protected]> writes:
> > > On Wed, Jan 17, 2024 at 9:49 AM Kyotaro Horiguchi
> > > <[email protected]> wrote:
> > >> On the other hand, SAVE_ERROR_TO takes 'error' or 'none', which
> > >> indicate "immediately error out" and 'just ignore the failure'
> > >> respectively, but these options hardly seem to denote a 'location',
> > >> and appear more like an 'action'. I somewhat suspect that this
> > >> parameter name intially conceived with the assupmtion that it would
> > >> take file names or similar parameters. I'm not sure if others will
> > >> agree, but I think the parameter name might not be the best
> > >> choice. For instance, considering the addition of the third value
> > >> 'log', something like on_error_action (error, ignore, log) would be
> > >> more intuitively understandable. What do you think?
> >
> > > Probably, but I'm not sure about that. The name SAVE_ERROR_TO assumes
> > > the next word will be location, not action. With some stretch we can
> > > assume 'error' to be location. I think it would be even more stretchy
> > > to think that SAVE_ERROR_TO is followed by action.
> >
> > The other problem with this terminology is that with 'none', what it
> > is doing is the exact opposite of "saving" the errors. I agree we
> > need a better name.
>
> Agreed.
>
> >
> > Kyotaro-san's suggestion isn't bad, though I might shorten it to
> > error_action {error|ignore|log} (or perhaps "stop" instead of "error")?
> > You will need a separate parameter anyway to specify the destination
> > of "log", unless "none" became an illegal table name when I wasn't
> > looking. I don't buy that one parameter that has some special values
> > while other values could be names will be a good design. Moreover,
> > what if we want to support (say) log-to-file along with log-to-table?
> > Trying to distinguish a file name from a table name without any other
> > context seems impossible.
>
> I've been thinking we can add more values to this option to log errors
> not only to the server logs but also to the error table (not sure
> details but I imagined an error table is created for each table on
> error), without an additional option for the destination name. The
> values would be like error_action {error|ignore|save-logs|save-table}.
>
another idea:
on_error {error|ignore|other_future_option}
if not specified then by default ERROR.
You can also specify ERROR or IGNORE for now.
I agree, the parameter "error_action" is better than "location".
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
@ 2024-01-18 02:15 ` torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: torikoshia @ 2024-01-18 02:15 UTC (permalink / raw)
To: jian he <[email protected]>; +Cc: Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Alexander Korotkov <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On 2024-01-18 10:10, jian he wrote:
> On Thu, Jan 18, 2024 at 8:57 AM Masahiko Sawada <[email protected]>
> wrote:
>>
>> On Thu, Jan 18, 2024 at 6:38 AM Tom Lane <[email protected]> wrote:
>> >
>> > Alexander Korotkov <[email protected]> writes:
>> > > On Wed, Jan 17, 2024 at 9:49 AM Kyotaro Horiguchi
>> > > <[email protected]> wrote:
>> > >> On the other hand, SAVE_ERROR_TO takes 'error' or 'none', which
>> > >> indicate "immediately error out" and 'just ignore the failure'
>> > >> respectively, but these options hardly seem to denote a 'location',
>> > >> and appear more like an 'action'. I somewhat suspect that this
>> > >> parameter name intially conceived with the assupmtion that it would
>> > >> take file names or similar parameters. I'm not sure if others will
>> > >> agree, but I think the parameter name might not be the best
>> > >> choice. For instance, considering the addition of the third value
>> > >> 'log', something like on_error_action (error, ignore, log) would be
>> > >> more intuitively understandable. What do you think?
>> >
>> > > Probably, but I'm not sure about that. The name SAVE_ERROR_TO assumes
>> > > the next word will be location, not action. With some stretch we can
>> > > assume 'error' to be location. I think it would be even more stretchy
>> > > to think that SAVE_ERROR_TO is followed by action.
>> >
>> > The other problem with this terminology is that with 'none', what it
>> > is doing is the exact opposite of "saving" the errors. I agree we
>> > need a better name.
>>
>> Agreed.
>>
>> >
>> > Kyotaro-san's suggestion isn't bad, though I might shorten it to
>> > error_action {error|ignore|log} (or perhaps "stop" instead of "error")?
>> > You will need a separate parameter anyway to specify the destination
>> > of "log", unless "none" became an illegal table name when I wasn't
>> > looking. I don't buy that one parameter that has some special values
>> > while other values could be names will be a good design. Moreover,
>> > what if we want to support (say) log-to-file along with log-to-table?
>> > Trying to distinguish a file name from a table name without any other
>> > context seems impossible.
>>
>> I've been thinking we can add more values to this option to log errors
>> not only to the server logs but also to the error table (not sure
>> details but I imagined an error table is created for each table on
>> error), without an additional option for the destination name. The
>> values would be like error_action {error|ignore|save-logs|save-table}.
>>
>
> another idea:
> on_error {error|ignore|other_future_option}
> if not specified then by default ERROR.
> You can also specify ERROR or IGNORE for now.
>
> I agree, the parameter "error_action" is better than "location".
I'm not sure whether error_action or on_error is better, but either way
"error_action error" and "on_error error" seems a bit odd to me.
I feel "stop" is better for both cases as Tom suggested.
--
Regards,
--
Atsushi Torikoshi
NTT DATA Group Corporation
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
@ 2024-01-18 07:59 ` Alexander Korotkov <[email protected]>
2024-01-18 08:01 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Pavel Stehule <[email protected]>
2024-01-18 08:33 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 12:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 3 replies; 94+ messages in thread
From: Alexander Korotkov @ 2024-01-18 07:59 UTC (permalink / raw)
To: torikoshia <[email protected]>; +Cc: jian he <[email protected]>; Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On Thu, Jan 18, 2024 at 4:16 AM torikoshia <[email protected]> wrote:
> On 2024-01-18 10:10, jian he wrote:
> > On Thu, Jan 18, 2024 at 8:57 AM Masahiko Sawada <[email protected]>
> > wrote:
> >> On Thu, Jan 18, 2024 at 6:38 AM Tom Lane <[email protected]> wrote:
> >> > Kyotaro-san's suggestion isn't bad, though I might shorten it to
> >> > error_action {error|ignore|log} (or perhaps "stop" instead of "error")?
> >> > You will need a separate parameter anyway to specify the destination
> >> > of "log", unless "none" became an illegal table name when I wasn't
> >> > looking. I don't buy that one parameter that has some special values
> >> > while other values could be names will be a good design. Moreover,
> >> > what if we want to support (say) log-to-file along with log-to-table?
> >> > Trying to distinguish a file name from a table name without any other
> >> > context seems impossible.
> >>
> >> I've been thinking we can add more values to this option to log errors
> >> not only to the server logs but also to the error table (not sure
> >> details but I imagined an error table is created for each table on
> >> error), without an additional option for the destination name. The
> >> values would be like error_action {error|ignore|save-logs|save-table}.
> >>
> >
> > another idea:
> > on_error {error|ignore|other_future_option}
> > if not specified then by default ERROR.
> > You can also specify ERROR or IGNORE for now.
> >
> > I agree, the parameter "error_action" is better than "location".
>
> I'm not sure whether error_action or on_error is better, but either way
> "error_action error" and "on_error error" seems a bit odd to me.
> I feel "stop" is better for both cases as Tom suggested.
OK. What about this?
on_error {stop|ignore|other_future_option}
where other_future_option might be compound like "file 'copy.log'" or
"table 'copy_log'".
------
Regards,
Alexander Korotkov
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
@ 2024-01-18 08:01 ` Pavel Stehule <[email protected]>
2 siblings, 0 replies; 94+ messages in thread
From: Pavel Stehule @ 2024-01-18 08:01 UTC (permalink / raw)
To: Alexander Korotkov <[email protected]>; +Cc: torikoshia <[email protected]>; jian he <[email protected]>; Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
čt 18. 1. 2024 v 8:59 odesílatel Alexander Korotkov <[email protected]>
napsal:
> On Thu, Jan 18, 2024 at 4:16 AM torikoshia <[email protected]>
> wrote:
> > On 2024-01-18 10:10, jian he wrote:
> > > On Thu, Jan 18, 2024 at 8:57 AM Masahiko Sawada <[email protected]
> >
> > > wrote:
> > >> On Thu, Jan 18, 2024 at 6:38 AM Tom Lane <[email protected]> wrote:
> > >> > Kyotaro-san's suggestion isn't bad, though I might shorten it to
> > >> > error_action {error|ignore|log} (or perhaps "stop" instead of
> "error")?
> > >> > You will need a separate parameter anyway to specify the destination
> > >> > of "log", unless "none" became an illegal table name when I wasn't
> > >> > looking. I don't buy that one parameter that has some special
> values
> > >> > while other values could be names will be a good design. Moreover,
> > >> > what if we want to support (say) log-to-file along with
> log-to-table?
> > >> > Trying to distinguish a file name from a table name without any
> other
> > >> > context seems impossible.
> > >>
> > >> I've been thinking we can add more values to this option to log errors
> > >> not only to the server logs but also to the error table (not sure
> > >> details but I imagined an error table is created for each table on
> > >> error), without an additional option for the destination name. The
> > >> values would be like error_action {error|ignore|save-logs|save-table}.
> > >>
> > >
> > > another idea:
> > > on_error {error|ignore|other_future_option}
> > > if not specified then by default ERROR.
> > > You can also specify ERROR or IGNORE for now.
> > >
> > > I agree, the parameter "error_action" is better than "location".
> >
> > I'm not sure whether error_action or on_error is better, but either way
> > "error_action error" and "on_error error" seems a bit odd to me.
> > I feel "stop" is better for both cases as Tom suggested.
>
> OK. What about this?
> on_error {stop|ignore|other_future_option}
> where other_future_option might be compound like "file 'copy.log'" or
> "table 'copy_log'".
>
+1
it is consistent with psql
Regards
Pavel
>
> ------
> Regards,
> Alexander Korotkov
>
>
>
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
@ 2024-01-18 08:33 ` Masahiko Sawada <[email protected]>
2 siblings, 0 replies; 94+ messages in thread
From: Masahiko Sawada @ 2024-01-18 08:33 UTC (permalink / raw)
To: Alexander Korotkov <[email protected]>; +Cc: torikoshia <[email protected]>; jian he <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On Thu, Jan 18, 2024 at 4:59 PM Alexander Korotkov <[email protected]> wrote:
>
> On Thu, Jan 18, 2024 at 4:16 AM torikoshia <[email protected]> wrote:
> > On 2024-01-18 10:10, jian he wrote:
> > > On Thu, Jan 18, 2024 at 8:57 AM Masahiko Sawada <[email protected]>
> > > wrote:
> > >> On Thu, Jan 18, 2024 at 6:38 AM Tom Lane <[email protected]> wrote:
> > >> > Kyotaro-san's suggestion isn't bad, though I might shorten it to
> > >> > error_action {error|ignore|log} (or perhaps "stop" instead of "error")?
> > >> > You will need a separate parameter anyway to specify the destination
> > >> > of "log", unless "none" became an illegal table name when I wasn't
> > >> > looking. I don't buy that one parameter that has some special values
> > >> > while other values could be names will be a good design. Moreover,
> > >> > what if we want to support (say) log-to-file along with log-to-table?
> > >> > Trying to distinguish a file name from a table name without any other
> > >> > context seems impossible.
> > >>
> > >> I've been thinking we can add more values to this option to log errors
> > >> not only to the server logs but also to the error table (not sure
> > >> details but I imagined an error table is created for each table on
> > >> error), without an additional option for the destination name. The
> > >> values would be like error_action {error|ignore|save-logs|save-table}.
> > >>
> > >
> > > another idea:
> > > on_error {error|ignore|other_future_option}
> > > if not specified then by default ERROR.
> > > You can also specify ERROR or IGNORE for now.
> > >
> > > I agree, the parameter "error_action" is better than "location".
> >
> > I'm not sure whether error_action or on_error is better, but either way
> > "error_action error" and "on_error error" seems a bit odd to me.
> > I feel "stop" is better for both cases as Tom suggested.
>
> OK. What about this?
> on_error {stop|ignore|other_future_option}
> where other_future_option might be compound like "file 'copy.log'" or
> "table 'copy_log'".
+1
Regards,
--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
@ 2024-01-18 12:09 ` torikoshia <[email protected]>
2024-01-18 14:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2 siblings, 1 reply; 94+ messages in thread
From: torikoshia @ 2024-01-18 12:09 UTC (permalink / raw)
To: Alexander Korotkov <[email protected]>; +Cc: jian he <[email protected]>; Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On 2024-01-18 16:59, Alexander Korotkov wrote:
> On Thu, Jan 18, 2024 at 4:16 AM torikoshia <[email protected]>
> wrote:
>> On 2024-01-18 10:10, jian he wrote:
>> > On Thu, Jan 18, 2024 at 8:57 AM Masahiko Sawada <[email protected]>
>> > wrote:
>> >> On Thu, Jan 18, 2024 at 6:38 AM Tom Lane <[email protected]> wrote:
>> >> > Kyotaro-san's suggestion isn't bad, though I might shorten it to
>> >> > error_action {error|ignore|log} (or perhaps "stop" instead of "error")?
>> >> > You will need a separate parameter anyway to specify the destination
>> >> > of "log", unless "none" became an illegal table name when I wasn't
>> >> > looking. I don't buy that one parameter that has some special values
>> >> > while other values could be names will be a good design. Moreover,
>> >> > what if we want to support (say) log-to-file along with log-to-table?
>> >> > Trying to distinguish a file name from a table name without any other
>> >> > context seems impossible.
>> >>
>> >> I've been thinking we can add more values to this option to log errors
>> >> not only to the server logs but also to the error table (not sure
>> >> details but I imagined an error table is created for each table on
>> >> error), without an additional option for the destination name. The
>> >> values would be like error_action {error|ignore|save-logs|save-table}.
>> >>
>> >
>> > another idea:
>> > on_error {error|ignore|other_future_option}
>> > if not specified then by default ERROR.
>> > You can also specify ERROR or IGNORE for now.
>> >
>> > I agree, the parameter "error_action" is better than "location".
>>
>> I'm not sure whether error_action or on_error is better, but either
>> way
>> "error_action error" and "on_error error" seems a bit odd to me.
>> I feel "stop" is better for both cases as Tom suggested.
>
> OK. What about this?
> on_error {stop|ignore|other_future_option}
> where other_future_option might be compound like "file 'copy.log'" or
> "table 'copy_log'".
Thanks, also +1 from me.
--
Regards,
--
Atsushi Torikoshi
NTT DATA Group Corporation
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-18 12:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
@ 2024-01-18 14:59 ` jian he <[email protected]>
2024-01-19 12:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: jian he @ 2024-01-18 14:59 UTC (permalink / raw)
To: torikoshia <[email protected]>; +Cc: Alexander Korotkov <[email protected]>; Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Hi.
patch refactored based on "on_error {stop|ignore}"
doc changes:
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -43,7 +43,7 @@ COPY { <replaceable
class="parameter">table_name</replaceable> [ ( <replaceable
FORCE_QUOTE { ( <replaceable
class="parameter">column_name</replaceable> [, ...] ) | * }
FORCE_NOT_NULL { ( <replaceable
class="parameter">column_name</replaceable> [, ...] ) | * }
FORCE_NULL { ( <replaceable
class="parameter">column_name</replaceable> [, ...] ) | * }
- SAVE_ERROR_TO '<replaceable class="parameter">location</replaceable>'
+ ON_ERROR '<replaceable class="parameter">error_action</replaceable>'
ENCODING '<replaceable class="parameter">encoding_name</replaceable>'
</synopsis>
</refsynopsisdiv>
@@ -375,20 +375,20 @@ COPY { <replaceable
class="parameter">table_name</replaceable> [ ( <replaceable
</varlistentry>
<varlistentry>
- <term><literal>SAVE_ERROR_TO</literal></term>
+ <term><literal>ON_ERROR</literal></term>
<listitem>
<para>
- Specifies to save error information to <replaceable class="parameter">
- location</replaceable> when there is malformed data in the input.
- Currently, only <literal>error</literal> (default) and
<literal>none</literal>
+ Specifies which <replaceable class="parameter">
+ error_action</replaceable> to perform when there is malformed
data in the input.
+ Currently, only <literal>stop</literal> (default) and
<literal>ignore</literal>
values are supported.
- If the <literal>error</literal> value is specified,
+ If the <literal>stop</literal> value is specified,
<command>COPY</command> stops operation at the first error.
- If the <literal>none</literal> value is specified,
+ If the <literal>ignore</literal> value is specified,
<command>COPY</command> skips malformed data and continues copying data.
The option is allowed only in <command>COPY FROM</command>.
- The <literal>none</literal> value is allowed only when
- not using <literal>binary</literal> format.
+ Only <literal>stop</literal> value is allowed only when
+ using <literal>binary</literal> format.
</para>
Attachments:
[text/x-patch] copy_on_error.diff (17.8K, ../../CACJufxGJjj94XTWsD9eJaiE99CPRBkO1frvJWTJ-6NDpa+ksLg@mail.gmail.com/2-copy_on_error.diff)
download | inline diff:
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 85881ca0..c30baec1 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -43,7 +43,7 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
FORCE_QUOTE { ( <replaceable class="parameter">column_name</replaceable> [, ...] ) | * }
FORCE_NOT_NULL { ( <replaceable class="parameter">column_name</replaceable> [, ...] ) | * }
FORCE_NULL { ( <replaceable class="parameter">column_name</replaceable> [, ...] ) | * }
- SAVE_ERROR_TO '<replaceable class="parameter">location</replaceable>'
+ ON_ERROR '<replaceable class="parameter">error_action</replaceable>'
ENCODING '<replaceable class="parameter">encoding_name</replaceable>'
</synopsis>
</refsynopsisdiv>
@@ -375,20 +375,20 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
</varlistentry>
<varlistentry>
- <term><literal>SAVE_ERROR_TO</literal></term>
+ <term><literal>ON_ERROR</literal></term>
<listitem>
<para>
- Specifies to save error information to <replaceable class="parameter">
- location</replaceable> when there is malformed data in the input.
- Currently, only <literal>error</literal> (default) and <literal>none</literal>
+ Specifies which <replaceable class="parameter">
+ error_action</replaceable> to perform when there is malformed data in the input.
+ Currently, only <literal>stop</literal> (default) and <literal>ignore</literal>
values are supported.
- If the <literal>error</literal> value is specified,
+ If the <literal>stop</literal> value is specified,
<command>COPY</command> stops operation at the first error.
- If the <literal>none</literal> value is specified,
+ If the <literal>ignore</literal> value is specified,
<command>COPY</command> skips malformed data and continues copying data.
The option is allowed only in <command>COPY FROM</command>.
- The <literal>none</literal> value is allowed only when
- not using <literal>binary</literal> format.
+ Only <literal>stop</literal> value is allowed only when
+ using <literal>binary</literal> format.
</para>
</listitem>
</varlistentry>
@@ -577,7 +577,7 @@ COPY <replaceable class="parameter">count</replaceable>
<para>
<command>COPY</command> stops operation at the first error when
- <literal>SAVE_ERROR_TO</literal> is not specified. This
+ <literal>ON_ERROR</literal> is not specified. This
should not lead to problems in the event of a <command>COPY
TO</command>, but the target table will already have received
earlier rows in a <command>COPY FROM</command>. These rows will not
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index c36d7f1d..cc0786c6 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -395,39 +395,39 @@ defGetCopyHeaderChoice(DefElem *def, bool is_from)
}
/*
- * Extract a CopySaveErrorToChoice value from a DefElem.
+ * Extract a CopyOnErrorChoice value from a DefElem.
*/
-static CopySaveErrorToChoice
-defGetCopySaveErrorToChoice(DefElem *def, ParseState *pstate, bool is_from)
+static CopyOnErrorChoice
+defGetCopyOnErrorChoice(DefElem *def, ParseState *pstate, bool is_from)
{
char *sval;
if (!is_from)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("COPY SAVE_ERROR_TO cannot be used with COPY TO"),
+ errmsg("COPY ON_ERROR cannot be used with COPY TO"),
parser_errposition(pstate, def->location)));
/*
* If no parameter value given, assume the default value.
*/
if (def->arg == NULL)
- return COPY_SAVE_ERROR_TO_ERROR;
+ return COPY_ON_ERROR_STOP;
/*
- * Allow "error", or "none" values.
+ * Allow "stop", or "ignore" values.
*/
sval = defGetString(def);
- if (pg_strcasecmp(sval, "error") == 0)
- return COPY_SAVE_ERROR_TO_ERROR;
- if (pg_strcasecmp(sval, "none") == 0)
- return COPY_SAVE_ERROR_TO_NONE;
+ if (pg_strcasecmp(sval, "stop") == 0)
+ return COPY_ON_ERROR_STOP;
+ if (pg_strcasecmp(sval, "ignore") == 0)
+ return COPY_ON_ERROR_IGNORE;
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("COPY save_error_to \"%s\" not recognized", sval),
+ errmsg("COPY ON_ERROR \"%s\" not recognized", sval),
parser_errposition(pstate, def->location)));
- return COPY_SAVE_ERROR_TO_ERROR; /* keep compiler quiet */
+ return COPY_ON_ERROR_STOP; /* keep compiler quiet */
}
/*
@@ -455,7 +455,7 @@ ProcessCopyOptions(ParseState *pstate,
bool format_specified = false;
bool freeze_specified = false;
bool header_specified = false;
- bool save_error_to_specified = false;
+ bool on_error_specified = false;
ListCell *option;
/* Support external use for option sanity checking */
@@ -608,12 +608,12 @@ ProcessCopyOptions(ParseState *pstate,
defel->defname),
parser_errposition(pstate, defel->location)));
}
- else if (strcmp(defel->defname, "save_error_to") == 0)
+ else if (strcmp(defel->defname, "on_error") == 0)
{
- if (save_error_to_specified)
+ if (on_error_specified)
errorConflictingDefElem(defel, pstate);
- save_error_to_specified = true;
- opts_out->save_error_to = defGetCopySaveErrorToChoice(defel, pstate, is_from);
+ on_error_specified = true;
+ opts_out->on_error = defGetCopyOnErrorChoice(defel, pstate, is_from);
}
else
ereport(ERROR,
@@ -642,10 +642,10 @@ ProcessCopyOptions(ParseState *pstate,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cannot specify DEFAULT in BINARY mode")));
- if (opts_out->binary && opts_out->save_error_to != COPY_SAVE_ERROR_TO_ERROR)
+ if (opts_out->binary && opts_out->on_error != COPY_ON_ERROR_STOP)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("cannot specify SAVE_ERROR_TO in BINARY mode")));
+ errmsg("only ON_ERROR STOP is allowed in BINARY mode")));
/* Set defaults for omitted options */
if (!opts_out->delim)
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index 50e245d5..c956cfa4 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -657,7 +657,7 @@ CopyFrom(CopyFromState cstate)
Assert(cstate->rel);
Assert(list_length(cstate->range_table) == 1);
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR)
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP)
Assert(cstate->escontext);
/*
@@ -996,14 +996,14 @@ CopyFrom(CopyFromState cstate)
if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull))
break;
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR &&
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP &&
cstate->escontext->error_occurred)
{
/*
- * Soft error occured, skip this tuple and save error information
- * according to SAVE_ERROR_TO.
+ * Soft error occured, skip this tuple and deal with error information
+ * according to ON_ERROR.
*/
- if (cstate->opts.save_error_to == COPY_SAVE_ERROR_TO_NONE)
+ if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE)
/*
* Just make ErrorSaveContext ready for the next NextCopyFrom.
@@ -1307,7 +1307,7 @@ CopyFrom(CopyFromState cstate)
/* Done, clean up */
error_context_stack = errcallback.previous;
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR &&
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP &&
cstate->num_errors > 0)
ereport(NOTICE,
errmsg_plural("%llu row was skipped due to data type incompatibility",
@@ -1450,18 +1450,18 @@ BeginCopyFrom(ParseState *pstate,
}
}
- /* Set up soft error handler for SAVE_ERROR_TO */
- if (cstate->opts.save_error_to != COPY_SAVE_ERROR_TO_ERROR)
+ /* Set up soft error handler for ON_ERROR */
+ if (cstate->opts.on_error != COPY_ON_ERROR_STOP)
{
cstate->escontext = makeNode(ErrorSaveContext);
cstate->escontext->type = T_ErrorSaveContext;
cstate->escontext->error_occurred = false;
/*
- * Currently we only support COPY_SAVE_ERROR_TO_NONE. We'll add other
+ * Currently we only support COPY_ON_ERROR_IGNORE. We'll add other
* options later
*/
- if (cstate->opts.save_error_to == COPY_SAVE_ERROR_TO_NONE)
+ if (cstate->opts.on_error == COPY_ON_ERROR_IGNORE)
cstate->escontext->details_wanted = false;
}
else
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index 7207eb26..36214aab 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -956,7 +956,7 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
values[m] = ExecEvalExpr(defexprs[m], econtext, &nulls[m]);
}
- /* If SAVE_ERROR_TO is specified, skip rows with soft errors */
+ /* If ON_ERROR is specified with IGNORE, skip rows with soft errors */
else if (!InputFunctionCallSafe(&in_functions[m],
string,
typioparams[m],
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 6bfdb5f0..ada711d0 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2899,15 +2899,15 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH("FORMAT", "FREEZE", "DELIMITER", "NULL",
"HEADER", "QUOTE", "ESCAPE", "FORCE_QUOTE",
"FORCE_NOT_NULL", "FORCE_NULL", "ENCODING", "DEFAULT",
- "SAVE_ERROR_TO");
+ "ON_ERROR");
/* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "FORMAT"))
COMPLETE_WITH("binary", "csv", "text");
- /* Complete COPY <sth> FROM filename WITH (SAVE_ERROR_TO */
- else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "SAVE_ERROR_TO"))
- COMPLETE_WITH("error", "none");
+ /* Complete COPY <sth> FROM filename WITH (ON_ERROR */
+ else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "WITH", "(", "ON_ERROR"))
+ COMPLETE_WITH("stop", "ignore");
/* Complete COPY <sth> FROM <sth> WITH (<options>) */
else if (Matches("COPY|\\copy", MatchAny, "FROM", MatchAny, "WITH", MatchAny))
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index 8972c618..78af1b0e 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -34,11 +34,11 @@ typedef enum CopyHeaderChoice
* Represents where to save input processing errors. More values to be added
* in the future.
*/
-typedef enum CopySaveErrorToChoice
+typedef enum CopyOnErrorChoice
{
- COPY_SAVE_ERROR_TO_ERROR = 0, /* immediately throw errors */
- COPY_SAVE_ERROR_TO_NONE, /* ignore errors */
-} CopySaveErrorToChoice;
+ COPY_ON_ERROR_STOP = 0, /* immediately throw errors, default */
+ COPY_ON_ERROR_IGNORE, /* ignore errors */
+} CopyOnErrorChoice;
/*
* A struct to hold COPY options, in a parsed form. All of these are related
@@ -72,7 +72,7 @@ typedef struct CopyFormatOptions
bool force_null_all; /* FORCE_NULL *? */
bool *force_null_flags; /* per-column CSV FN flags */
bool convert_selectively; /* do selective binary conversion? */
- CopySaveErrorToChoice save_error_to; /* where to save error information */
+ CopyOnErrorChoice on_error; /* what to do when error happened */
List *convert_select; /* list of column names (can be NIL) */
} CopyFormatOptions;
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 42cbcb2e..d982ae4f 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -77,21 +77,21 @@ COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii');
ERROR: conflicting or redundant options
LINE 1: COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii...
^
-COPY x from stdin (save_error_to none,save_error_to none);
+COPY x from stdin (ON_ERROR ignore, ON_ERROR ignore);
ERROR: conflicting or redundant options
-LINE 1: COPY x from stdin (save_error_to none,save_error_to none);
- ^
+LINE 1: COPY x from stdin (ON_ERROR ignore, ON_ERROR ignore);
+ ^
-- incorrect options
COPY x to stdin (format BINARY, delimiter ',');
ERROR: cannot specify DELIMITER in BINARY mode
COPY x to stdin (format BINARY, null 'x');
ERROR: cannot specify NULL in BINARY mode
-COPY x from stdin (format BINARY, save_error_to none);
-ERROR: cannot specify SAVE_ERROR_TO in BINARY mode
-COPY x to stdin (save_error_to none);
-ERROR: COPY SAVE_ERROR_TO cannot be used with COPY TO
-LINE 1: COPY x to stdin (save_error_to none);
- ^
+COPY x from stdin (format BINARY, ON_ERROR ignore);
+ERROR: only ON_ERROR STOP is allowed in BINARY mode
+COPY x from stdin (ON_ERROR unsupported);
+ERROR: COPY ON_ERROR "unsupported" not recognized
+LINE 1: COPY x from stdin (ON_ERROR unsupported);
+ ^
COPY x to stdin (format TEXT, force_quote(a));
ERROR: COPY FORCE_QUOTE requires CSV mode
COPY x from stdin (format CSV, force_quote(a));
@@ -104,9 +104,9 @@ COPY x to stdout (format TEXT, force_null(a));
ERROR: COPY FORCE_NULL requires CSV mode
COPY x to stdin (format CSV, force_null(a));
ERROR: COPY FORCE_NULL cannot be used with COPY TO
-COPY x to stdin (format BINARY, save_error_to unsupported);
-ERROR: COPY SAVE_ERROR_TO cannot be used with COPY TO
-LINE 1: COPY x to stdin (format BINARY, save_error_to unsupported);
+COPY x to stdin (format BINARY, ON_ERROR unsupported);
+ERROR: COPY ON_ERROR cannot be used with COPY TO
+LINE 1: COPY x to stdin (format BINARY, ON_ERROR unsupported);
^
-- too many columns in column list: should fail
COPY x (a, b, c, d, e, d, c) from stdin;
@@ -724,12 +724,12 @@ SELECT * FROM instead_of_insert_tbl;
(2 rows)
COMMIT;
--- tests for SAVE_ERROR_TO option
+-- tests for ON_ERROR option
CREATE TABLE check_ign_err (n int, m int[], k int);
-COPY check_ign_err FROM STDIN WITH (save_error_to error);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR stop);
ERROR: invalid input syntax for type integer: "a"
CONTEXT: COPY check_ign_err, line 2, column n: "a"
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR ignore);
NOTICE: 4 rows were skipped due to data type incompatibility
SELECT * FROM check_ign_err;
n | m | k
@@ -740,15 +740,15 @@ SELECT * FROM check_ign_err;
-- test datatype error that can't be handled as soft: should fail
CREATE TABLE hard_err(foo widget);
-COPY hard_err FROM STDIN WITH (save_error_to none);
+COPY hard_err FROM STDIN WITH (ON_ERROR ignore);
ERROR: invalid input syntax for type widget: "1"
CONTEXT: COPY hard_err, line 1, column foo: "1"
-- test missing data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR ignore);
ERROR: missing data for column "k"
CONTEXT: COPY check_ign_err, line 1: "1 {1}"
-- test extra data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR ignore);
ERROR: extra data after last expected column
CONTEXT: COPY check_ign_err, line 1: "1 {1} 3 abc"
-- clean up
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index c48d5563..73b2e688 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -66,20 +66,20 @@ COPY x from stdin (force_not_null (a), force_not_null (b));
COPY x from stdin (force_null (a), force_null (b));
COPY x from stdin (convert_selectively (a), convert_selectively (b));
COPY x from stdin (encoding 'sql_ascii', encoding 'sql_ascii');
-COPY x from stdin (save_error_to none,save_error_to none);
+COPY x from stdin (ON_ERROR ignore, ON_ERROR ignore);
-- incorrect options
COPY x to stdin (format BINARY, delimiter ',');
COPY x to stdin (format BINARY, null 'x');
-COPY x from stdin (format BINARY, save_error_to none);
-COPY x to stdin (save_error_to none);
+COPY x from stdin (format BINARY, ON_ERROR ignore);
+COPY x from stdin (ON_ERROR unsupported);
COPY x to stdin (format TEXT, force_quote(a));
COPY x from stdin (format CSV, force_quote(a));
COPY x to stdout (format TEXT, force_not_null(a));
COPY x to stdin (format CSV, force_not_null(a));
COPY x to stdout (format TEXT, force_null(a));
COPY x to stdin (format CSV, force_null(a));
-COPY x to stdin (format BINARY, save_error_to unsupported);
+COPY x to stdin (format BINARY, ON_ERROR unsupported);
-- too many columns in column list: should fail
COPY x (a, b, c, d, e, d, c) from stdin;
@@ -498,9 +498,9 @@ test1
SELECT * FROM instead_of_insert_tbl;
COMMIT;
--- tests for SAVE_ERROR_TO option
+-- tests for ON_ERROR option
CREATE TABLE check_ign_err (n int, m int[], k int);
-COPY check_ign_err FROM STDIN WITH (save_error_to error);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR stop);
1 {1} 1
a {2} 2
3 {3} 3333333333
@@ -508,7 +508,7 @@ a {2} 2
5 {5} 5
\.
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR ignore);
1 {1} 1
a {2} 2
3 {3} 3333333333
@@ -520,17 +520,17 @@ SELECT * FROM check_ign_err;
-- test datatype error that can't be handled as soft: should fail
CREATE TABLE hard_err(foo widget);
-COPY hard_err FROM STDIN WITH (save_error_to none);
+COPY hard_err FROM STDIN WITH (ON_ERROR ignore);
1
\.
-- test missing data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR ignore);
1 {1}
\.
-- test extra data: should fail
-COPY check_ign_err FROM STDIN WITH (save_error_to none);
+COPY check_ign_err FROM STDIN WITH (ON_ERROR ignore);
1 {1} 3 abc
\.
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 29fd1cae..456461f8 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -478,6 +478,7 @@ CopyHeaderChoice
CopyInsertMethod
CopyMultiInsertBuffer
CopyMultiInsertInfo
+CopyOnErrorChoice
CopySource
CopyStmt
CopyToState
@@ -4041,4 +4042,3 @@ manifest_writer
rfile
ws_options
ws_file_info
-CopySaveErrorToChoice
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-18 12:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 14:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
@ 2024-01-19 12:37 ` torikoshia <[email protected]>
2024-01-19 13:27 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: torikoshia @ 2024-01-19 12:37 UTC (permalink / raw)
To: jian he <[email protected]>; +Cc: Alexander Korotkov <[email protected]>; Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On 2024-01-18 23:59, jian he wrote:
> Hi.
> patch refactored based on "on_error {stop|ignore}"
> doc changes:
>
> --- a/doc/src/sgml/ref/copy.sgml
> +++ b/doc/src/sgml/ref/copy.sgml
> @@ -43,7 +43,7 @@ COPY { <replaceable
> class="parameter">table_name</replaceable> [ ( <replaceable
> FORCE_QUOTE { ( <replaceable
> class="parameter">column_name</replaceable> [, ...] ) | * }
> FORCE_NOT_NULL { ( <replaceable
> class="parameter">column_name</replaceable> [, ...] ) | * }
> FORCE_NULL { ( <replaceable
> class="parameter">column_name</replaceable> [, ...] ) | * }
> - SAVE_ERROR_TO '<replaceable
> class="parameter">location</replaceable>'
> + ON_ERROR '<replaceable
> class="parameter">error_action</replaceable>'
> ENCODING '<replaceable
> class="parameter">encoding_name</replaceable>'
> </synopsis>
> </refsynopsisdiv>
> @@ -375,20 +375,20 @@ COPY { <replaceable
> class="parameter">table_name</replaceable> [ ( <replaceable
> </varlistentry>
>
> <varlistentry>
> - <term><literal>SAVE_ERROR_TO</literal></term>
> + <term><literal>ON_ERROR</literal></term>
> <listitem>
> <para>
> - Specifies to save error information to <replaceable
> class="parameter">
> - location</replaceable> when there is malformed data in the
> input.
> - Currently, only <literal>error</literal> (default) and
> <literal>none</literal>
> + Specifies which <replaceable class="parameter">
> + error_action</replaceable> to perform when there is malformed
> data in the input.
> + Currently, only <literal>stop</literal> (default) and
> <literal>ignore</literal>
> values are supported.
> - If the <literal>error</literal> value is specified,
> + If the <literal>stop</literal> value is specified,
> <command>COPY</command> stops operation at the first error.
> - If the <literal>none</literal> value is specified,
> + If the <literal>ignore</literal> value is specified,
> <command>COPY</command> skips malformed data and continues
> copying data.
> The option is allowed only in <command>COPY FROM</command>.
> - The <literal>none</literal> value is allowed only when
> - not using <literal>binary</literal> format.
> + Only <literal>stop</literal> value is allowed only when
> + using <literal>binary</literal> format.
> </para>
Thanks for making the patch!
Here are some comments:
> - The <literal>none</literal> value is allowed only when
> - not using <literal>binary</literal> format.
> + Only <literal>stop</literal> value is allowed only when
> + using <literal>binary</literal> format.
The second 'only' may be unnecessary.
> - /* If SAVE_ERROR_TO is specified, skip rows
> with soft errors */
> + /* If ON_ERROR is specified with IGNORE, skip
> rows with soft errors */
This is correct now, but considering future works which add other
options like "file 'copy.log'" and
"table 'copy_log'", it may be better not to limit the case to 'IGNORE'.
How about something like this?
If ON_ERROR is specified and the value is not STOP, skip rows with
soft errors
> -COPY x from stdin (format BINARY, save_error_to none);
> -COPY x to stdin (save_error_to none);
> +COPY x from stdin (format BINARY, ON_ERROR ignore);
> +COPY x from stdin (ON_ERROR unsupported);
> COPY x to stdin (format TEXT, force_quote(a));
> COPY x from stdin (format CSV, force_quote(a));
In the existing test for copy2.sql, the COPY options are written in
lower case(e.g. 'format') and option value(e.g. 'BINARY') are written in
upper case.
It would be more consistent to align them.
--
Regards,
--
Atsushi Torikoshi
NTT DATA Group Corporation
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-18 12:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 14:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-19 12:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
@ 2024-01-19 13:27 ` Alexander Korotkov <[email protected]>
2024-01-19 14:26 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Alexander Korotkov @ 2024-01-19 13:27 UTC (permalink / raw)
To: torikoshia <[email protected]>; +Cc: jian he <[email protected]>; Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Hi!
On Fri, Jan 19, 2024 at 2:37 PM torikoshia <[email protected]> wrote:
> Thanks for making the patch!
The patch is pushed! The proposed changes are incorporated excluding this.
> > - /* If SAVE_ERROR_TO is specified, skip rows
> > with soft errors */
> > + /* If ON_ERROR is specified with IGNORE, skip
> > rows with soft errors */
>
> This is correct now, but considering future works which add other
> options like "file 'copy.log'" and
> "table 'copy_log'", it may be better not to limit the case to 'IGNORE'.
> How about something like this?
>
> If ON_ERROR is specified and the value is not STOP, skip rows with
> soft errors
I think when we have more options, then we wouldn't just skip rows
with soft errors but rather save them. So, I left this comment as is
for now.
------
Regards,
Alexander Korotkov
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features)
2024-01-17 21:06 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Tom Lane <[email protected]>
2024-01-18 00:56 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-18 02:15 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 07:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
2024-01-18 12:09 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-18 14:59 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) jian he <[email protected]>
2024-01-19 12:37 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) torikoshia <[email protected]>
2024-01-19 13:27 ` Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alexander Korotkov <[email protected]>
@ 2024-01-19 14:26 ` torikoshia <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: torikoshia @ 2024-01-19 14:26 UTC (permalink / raw)
To: Alexander Korotkov <[email protected]>; +Cc: jian he <[email protected]>; Masahiko Sawada <[email protected]>; Tom Lane <[email protected]>; Kyotaro Horiguchi <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; pgsql-hackers; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
On 2024-01-19 22:27, Alexander Korotkov wrote:
> Hi!
>
> On Fri, Jan 19, 2024 at 2:37 PM torikoshia <[email protected]>
> wrote:
>> Thanks for making the patch!
>
> The patch is pushed! The proposed changes are incorporated excluding
> this.
>
>> > - /* If SAVE_ERROR_TO is specified, skip rows
>> > with soft errors */
>> > + /* If ON_ERROR is specified with IGNORE, skip
>> > rows with soft errors */
>>
>> This is correct now, but considering future works which add other
>> options like "file 'copy.log'" and
>> "table 'copy_log'", it may be better not to limit the case to
>> 'IGNORE'.
>> How about something like this?
>>
>> If ON_ERROR is specified and the value is not STOP, skip rows with
>> soft errors
>
> I think when we have more options, then we wouldn't just skip rows
> with soft errors but rather save them. So, I left this comment as is
> for now.
Agreed.
Thanks for the notification!
>
> ------
> Regards,
> Alexander Korotkov
--
Regards,
--
Atsushi Torikoshi
NTT DATA Group Corporation
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v13 5/8] Row pattern recognition patch (executor).
@ 2024-01-22 09:45 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-01-22 09:45 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1435 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 26 +
4 files changed, 1490 insertions(+), 14 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 62d028379b..28d1110b8a 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,40 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet {
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos {
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -182,8 +218,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +232,42 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet *string_set_init(void);
+static void string_set_add(StringSet *string_set, StringInfo str);
+static StringInfo string_set_get(StringSet *string_set, int index);
+static int string_set_get_size(StringSet *string_set);
+static void string_set_discard(StringSet *string_set);
+static VariablePos *variable_pos_init(void);
+static void variable_pos_register(VariablePos *variable_pos, char initial, int pos);
+static bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2);
+static int variable_pos_fetch(VariablePos *variable_pos, char initial, int index);
+static void variable_pos_discard(VariablePos *variable_pos);
/*
* initialize_windowaggregate
@@ -673,6 +743,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +849,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +862,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -862,7 +939,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1009,29 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate, winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +1045,11 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1065,28 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate, winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate, winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1115,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1136,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP
+ * TO PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1240,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2204,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2374,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear existing
+ * reduced frame info so that we newly calculate the info starting from
+ * current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2552,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2650,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2844,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2884,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +2984,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3346,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3666,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3780,21 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /* RPR cares about frame head pos. Need to call update_frameheadpos */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3861,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3885,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3922,1097 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1; get_reduced_frame_map(winstate,i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, state, pos);
+ break;
+ }
+
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, rtn, pos);
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * Create reduced frame map
+ */
+static
+void create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext, REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * Clear reduced frame map
+ */
+static
+void clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * Get reduced frame map specified by pos
+ */
+static
+int get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int str_set_index = 0;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos, i;
+
+ /*
+ * Set of pattern variables evaluated to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier.
+ * If it does not, we can just apply the pattern to each row.
+ * If it succeeds, we are done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s", pos, vname);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+ elog(DEBUG1, "expression result is false or out of frame");
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+ elog(DEBUG1, "pattern matched");
+
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included.
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ elog(DEBUG1, "search_str_set started");
+ num_matched_rows = search_str_set(pattern_str->data, str_set, variable_pos);
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * Perform pattern matching using pattern against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. For example, if DEFINE has variables START, UP and
+ * DOWN, PATTERN HAS START, UP and DOWN, then the initials in PATTERN will be
+ * 'a', 'b' and 'c'.
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows.
+ */
+static
+int search_str_set(char *pattern, StringSet *str_set, VariablePos *variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set, *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+ elog(DEBUG1, "index: %d", index);
+
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size ; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+ elog(DEBUG1, "discard this old set because shorter match: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "keep this old set: %s", old->data);
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+ elog(DEBUG1, "discard this old set: %s", old->data);
+ continue;
+ }
+
+ elog(DEBUG1, "str->data: %s", str->data);
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed
+ * entries that have shorter match length.
+ * Mark them as "discard" so that they are
+ * discarded in the next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size = string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size; new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char = new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /* mark this set to discard in the next round */
+ appendStringInfoChar(new, DISCARD_CHAR);
+ elog(DEBUG1, "add discard char: %s", new->data);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+ elog(DEBUG1, "target string: %s", s->data);
+
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text, *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr in the first
+ * place is, it errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet *string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void string_set_add(StringSet *string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo string_set_get(StringSet *string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 ||index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * Returns the size of StringSet.
+ */
+static
+int string_set_get_size(StringSet *string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void string_set_discard(StringSet *string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos *variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void variable_pos_register(VariablePos *variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2)
+{
+ int index1, index2;
+ int pos1, pos2;
+
+ for (index1 = 0; ; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0; ; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int variable_pos_fetch(VariablePos *variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * Discard VariablePos
+ */
+static
+void variable_pos_discard(VariablePos *variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 095de7741d..67a890f992 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index ad74e07dbb..a34ddaa385 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10452,6 +10452,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 561fdd98f1..888dad4c7d 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2470,6 +2470,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2518,6 +2523,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2554,6 +2568,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Mon_Jan_22_19_26_18_2024_011)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v13-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
@ 2024-02-13 06:24 Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-02-13 06:24 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 13.02.24 03:01, Jeff Davis wrote:
> 1. The SQL spec mentions the capitalization of "ß" as "SS"
> specifically. Should UCS_BASIC use the unconditional mappings in
> SpecialCasing.txt? I already have some code to do that (not posted
> yet).
It is my understanding that "correct" Unicode case conversion needs to
use at least some parts of SpecialCasing.txt. The header of the file says
"For compatibility, the UnicodeData.txt file only contains simple case
mappings for characters where they are one-to-one and independent of
context and language. The data in this file, combined with the simple
case mappings in UnicodeData.txt, defines the full case mappings [...]"
I read this as, just using UnicodeData.txt by itself is incomplete.
I think we need to use the "Unconditional" mappings and the "Conditional
Language-Insensitive" mappings (which is just Greek sigma). Obviously,
skip the "Language-Sensitive" mappings.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-02-27 03:01 ` Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-02-27 03:01 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Tue, 2024-02-13 at 07:24 +0100, Peter Eisentraut wrote:
> It is my understanding that "correct" Unicode case conversion needs
> to
> use at least some parts of SpecialCasing.txt.
...
> I think we need to use the "Unconditional" mappings and the
> "Conditional
> Language-Insensitive" mappings (which is just Greek sigma).
> Obviously,
> skip the "Language-Sensitive" mappings.
Attached a new series.
Overall I'm quite happy with this feature as well as the recent
updates. It expands a lot on what behavior we can actually document;
the character semantics are nearly as good as ICU; it's fast; and it
eliminates what is arguably the last reason to use libc ("C collation
combined with some other CTYPE").
Changes:
* Added a doc update for the "standard collations" (tiny patch, mostly
separate) which clarifies the collations that are always available, and
describes them a bit better
* Added built-in locale "UCS_BASIC" (is that name confusing?) which
uses full case mapping and the standard properties:
- "ß" uppercases to "SS"
- "Σ" usually lowercases to "σ", except when the Final_Sigma
condition is met, in which case it lowercases to "ς"
- initcap() uses titlecase variants ("dž" changes to "Dž")
- in patterns/regexes, symbols (like "=") are not treated as
punctuation
* Changed the UCS_BASIC collation to use the builtin "UCS_BASIC"
locale with Unicode semantis. At first I was skeptical because it's a
behavior change, and I am still not sure we want to do that. But doing
so would take us closer to both the SQL spec as well as Unicode; and
also this kind of character behavior change is less likely to cause a
problem than a collation behavior change.
* The built-in locale "C.UTF-8" still exists, which uses Unicode
simple case mapping and the POSIX compatible properties (no change
here).
Implementation-wise:
* I introduced the CaseKind enum, which seemed to clean up a few
things and reduce code duplication between upper/lower/titlecase. It
also leaves room for introducing case folding later.
* Introduced a "case-ignorable" table to properly implement the
Final_Sigma rule.
Loose ends:
* Right now you can't mix all of the full case mapping behavior with
INITCAP(), it just does simple titlecase mapping. I'm not sure we want
to get too fancy here; after all, INITCAP() is not a SQL standard
function and it's documented in a narrow fashion that doesn't seem to
leave a lot of room to be very smart. ICU does a few extra things
beyond what I did:
- it accepts a word break iterator to the case conversion function
- it provides some built-in word break iterators
- it also has some configurable "break adjustment" behavior[1][2]
which re-aligns the start of the word, and I'm not entirely sure why
that isn't done in the word break iterator or the titlecasing rules
Regards,
Jeff Davis
[1]
https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/stringoptions_8h.html#a4975f537b9960f0330b23...
[2]
https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/stringoptions_8h.html#afc65fa226cac9b8eeef0e...
Attachments:
[text/x-patch] v18-0001-Documentation-update-for-Standard-Collations.patch (5.0K, ../../[email protected]/2-v18-0001-Documentation-update-for-Standard-Collations.patch)
download | inline diff:
From 182de3bf87f46f5c3f321a304ec2e39112a972b9 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 19 Feb 2024 15:21:39 -0800
Subject: [PATCH v18 1/6] Documentation update for Standard Collations.
---
doc/src/sgml/charset.sgml | 79 ++++++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 31 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 74783d148f..4422b0cc92 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -788,55 +788,72 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<title>Standard Collations</title>
<para>
- On all platforms, the collations named <literal>default</literal>,
- <literal>C</literal>, and <literal>POSIX</literal> are available. Additional
- collations may be available depending on operating system support.
- The <literal>default</literal> collation selects the <symbol>LC_COLLATE</symbol>
- and <symbol>LC_CTYPE</symbol> values specified at database creation time.
- The <literal>C</literal> and <literal>POSIX</literal> collations both specify
- <quote>traditional C</quote> behavior, in which only the ASCII letters
- <quote><literal>A</literal></quote> through <quote><literal>Z</literal></quote>
- are treated as letters, and sorting is done strictly by character
- code byte values.
- </para>
-
- <note>
- <para>
- The <literal>C</literal> and <literal>POSIX</literal> locales may behave
- differently depending on the database encoding.
- </para>
- </note>
-
- <para>
- Additionally, two SQL standard collation names are available:
+ On all platforms, the collations following collations are supported:
<variablelist>
<varlistentry>
- <term><literal>unicode</literal></term>
+ <term><literal>UNICODE</literal></term>
<listitem>
<para>
- This collation sorts using the Unicode Collation Algorithm with the
- Default Unicode Collation Element Table. It is available in all
- encodings. ICU support is required to use this collation. (This
- collation has the same behavior as the ICU root locale; see <xref
+ This SQL standard collation sorts using the Unicode Collation
+ Algorithm with the Default Unicode Collation Element Table. It is
+ available in all encodings. ICU support is required to use this
+ collation, and behavior may change if Postgres is built with a
+ different version of ICU. (This collation has the same behavior as
+ the ICU root locale; see <xref
linkend="collation-managing-predefined-icu-und-x-icu"/>.)
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>ucs_basic</literal></term>
+ <term><literal>UCS_BASIC</literal></term>
<listitem>
<para>
- This collation sorts by Unicode code point. It is only available for
- encoding <literal>UTF8</literal>. (This collation has the same
- behavior as the libc locale specification <literal>C</literal> in
- <literal>UTF8</literal> encoding.)
+ This SQL standard collation sorts by Unicode code point. Behavior is
+ efficient and stable across all versions. Case mapping and pattern
+ matching behavior is based on simple ASCII semantics. It is only
+ available for encoding <literal>UTF8</literal>. (This collation has
+ the same behavior as the libc locale specification
+ <literal>C</literal> in <literal>UTF8</literal> encoding.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
+ <listitem>
+ <para>
+ The <literal>C</literal> and <literal>POSIX</literal> collations both
+ specify <quote>traditional C</quote> behavior, in which only the ASCII
+ letters <quote><literal>A</literal></quote> through
+ <quote><literal>Z</literal></quote> are treated as letters, and
+ sorting is done strictly by character code byte values. Case mapping
+ and pattern matching behavior is based on simple ASCII
+ semantics. Behavior is efficient and stable across all versions for a
+ given database encoding, but behavior may vary between different
+ database encodings.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>default</literal></term>
+ <listitem>
+ <para>
+ The <literal>default</literal> collation selects the locale specified
+ at database creation time.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
+
+ <para>
+ Additional collations may be available depending on operating system
+ support. The efficiency and stability of these additional collations
+ depend on the collation provider, the provider version, and the locale.
+ </para>
</sect3>
<sect3 id="collation-managing-predefined">
--
2.34.1
[text/x-patch] v18-0002-Add-Unicode-property-tables.patch (105.9K, ../../[email protected]/3-v18-0002-Add-Unicode-property-tables.patch)
download | inline diff:
From 4a5c4d789c6489082e35ecd653a4d45f016fb3ef Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 18 Nov 2023 15:34:24 -0800
Subject: [PATCH v18 2/6] Add Unicode property tables.
Provide functions to test for regex character classes (e.g. 'alpha',
'punct') using Unicode properties.
---
src/common/unicode/Makefile | 6 +-
src/common/unicode/category_test.c | 225 +-
.../generate-unicode_category_table.pl | 308 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_category.c | 289 +-
src/include/common/unicode_category.h | 27 +-
src/include/common/unicode_category_table.h | 3030 ++++++++++++++++-
7 files changed, 3795 insertions(+), 94 deletions(-)
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index 04d81dd5cb..27f0408d8b 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -29,13 +29,13 @@ update-unicode: unicode_category_table.h unicode_east_asian_fw_table.h unicode_n
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
$(PERL) $< --version $(UNICODE_VERSION)
-unicode_category_table.h: generate-unicode_category_table.pl UnicodeData.txt
+unicode_category_table.h: generate-unicode_category_table.pl DerivedCoreProperties.txt PropList.txt UnicodeData.txt
$(PERL) $<
# Generation of conversion tables used for string normalization with
@@ -82,4 +82,4 @@ clean:
rm -f $(OBJS) category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/category_test.c b/src/common/unicode/category_test.c
index f1aaac0f61..8d1732b448 100644
--- a/src/common/unicode/category_test.c
+++ b/src/common/unicode/category_test.c
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------
* category_test.c
- * Program to test Unicode general category functions.
+ * Program to test Unicode general category and character properties.
*
* Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
*
@@ -14,17 +14,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
#ifdef USE_ICU
#include <unicode/uchar.h>
#endif
-#include "common/unicode_category.h"
+#include <wctype.h>
+
#include "common/unicode_version.h"
+#include "common/unicode_category.h"
+
+static int pg_unicode_version = 0;
+#ifdef USE_ICU
+static int icu_unicode_version = 0;
+#endif
/*
* Parse version into integer for easy comparison.
*/
-#ifdef USE_ICU
static int
parse_unicode_version(const char *version)
{
@@ -39,57 +44,175 @@ parse_unicode_version(const char *version)
return major * 100 + minor;
}
-#endif
+#ifdef USE_ICU
/*
- * Exhaustively test that the Unicode category for each codepoint matches that
- * returned by ICU.
+ * Test Postgres Unicode tables by comparing with ICU. Test the General
+ * Category, as well as the properties Alphabetic, Lowercase, Uppercase,
+ * White_Space, and Hex_Digit.
*/
-int
-main(int argc, char **argv)
+static void
+icu_test()
{
-#ifdef USE_ICU
- int pg_unicode_version = parse_unicode_version(PG_UNICODE_VERSION);
- int icu_unicode_version = parse_unicode_version(U_UNICODE_VERSION);
+ int successful = 0;
int pg_skipped_codepoints = 0;
int icu_skipped_codepoints = 0;
- printf("category_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
- printf("category_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
-
- for (UChar32 code = 0; code <= 0x10ffff; code++)
+ for (pg_wchar code = 0; code <= 0x10ffff; code++)
{
uint8_t pg_category = unicode_category(code);
uint8_t icu_category = u_charType(code);
+ /* Property tests */
+ bool prop_alphabetic = pg_u_prop_alphabetic(code);
+ bool prop_lowercase = pg_u_prop_lowercase(code);
+ bool prop_uppercase = pg_u_prop_uppercase(code);
+ bool prop_cased = pg_u_prop_cased(code);
+ bool prop_case_ignorable = pg_u_prop_case_ignorable(code);
+ bool prop_white_space = pg_u_prop_white_space(code);
+ bool prop_hex_digit = pg_u_prop_hex_digit(code);
+ bool prop_join_control = pg_u_prop_join_control(code);
+
+ bool icu_prop_alphabetic = u_hasBinaryProperty(
+ code, UCHAR_ALPHABETIC);
+ bool icu_prop_lowercase = u_hasBinaryProperty(
+ code, UCHAR_LOWERCASE);
+ bool icu_prop_uppercase = u_hasBinaryProperty(
+ code, UCHAR_UPPERCASE);
+ bool icu_prop_cased = u_hasBinaryProperty(
+ code, UCHAR_CASED);
+ bool icu_prop_case_ignorable = u_hasBinaryProperty(
+ code, UCHAR_CASE_IGNORABLE);
+ bool icu_prop_white_space = u_hasBinaryProperty(
+ code, UCHAR_WHITE_SPACE);
+ bool icu_prop_hex_digit = u_hasBinaryProperty(
+ code, UCHAR_HEX_DIGIT);
+ bool icu_prop_join_control = u_hasBinaryProperty(
+ code, UCHAR_JOIN_CONTROL);
+
+ /*
+ * Compare with ICU for character classes using:
+ *
+ * https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/uchar_8h.html#details
+ *
+ * which describes how to use ICU to test for membership in regex
+ * character classes.
+ *
+ * NB: the document suggests testing for some properties such as
+ * UCHAR_POSIX_ALNUM, but that doesn't mean that we're testing for the
+ * "POSIX Compatible" character classes.
+ */
+ bool isalpha = pg_u_isalpha(code);
+ bool islower = pg_u_islower(code);
+ bool isupper = pg_u_isupper(code);
+ bool ispunct = pg_u_ispunct(code, false);
+ bool isdigit = pg_u_isdigit(code, false);
+ bool isxdigit = pg_u_isxdigit(code, false);
+ bool isalnum = pg_u_isalnum(code, false);
+ bool isspace = pg_u_isspace(code);
+ bool isblank = pg_u_isblank(code);
+ bool iscntrl = pg_u_iscntrl(code);
+ bool isgraph = pg_u_isgraph(code);
+ bool isprint = pg_u_isprint(code);
+
+ bool icu_isalpha = u_isUAlphabetic(code);
+ bool icu_islower = u_isULowercase(code);
+ bool icu_isupper = u_isUUppercase(code);
+ bool icu_ispunct = u_ispunct(code);
+ bool icu_isdigit = u_isdigit(code);
+ bool icu_isxdigit = u_hasBinaryProperty(code,
+ UCHAR_POSIX_XDIGIT);
+ bool icu_isalnum = u_hasBinaryProperty(code,
+ UCHAR_POSIX_ALNUM);
+ bool icu_isspace = u_isUWhiteSpace(code);
+ bool icu_isblank = u_isblank(code);
+ bool icu_iscntrl = icu_category == PG_U_CONTROL;
+ bool icu_isgraph = u_hasBinaryProperty(code,
+ UCHAR_POSIX_GRAPH);
+ bool icu_isprint = u_hasBinaryProperty(code,
+ UCHAR_POSIX_PRINT);
+
+ /*
+ * A version mismatch means that some assigned codepoints in the newer
+ * version may be unassigned in the older version. That's OK, though
+ * the test will not cover those codepoints marked unassigned in the
+ * older version (that is, it will no longer be an exhaustive test).
+ */
+ if (pg_category == PG_U_UNASSIGNED &&
+ icu_category != PG_U_UNASSIGNED &&
+ pg_unicode_version < icu_unicode_version)
+ {
+ pg_skipped_codepoints++;
+ continue;
+ }
+
+ if (icu_category == PG_U_UNASSIGNED &&
+ pg_category != PG_U_UNASSIGNED &&
+ icu_unicode_version < pg_unicode_version)
+ {
+ icu_skipped_codepoints++;
+ continue;
+ }
+
if (pg_category != icu_category)
{
- /*
- * A version mismatch means that some assigned codepoints in the
- * newer version may be unassigned in the older version. That's
- * OK, though the test will not cover those codepoints marked
- * unassigned in the older version (that is, it will no longer be
- * an exhaustive test).
- */
- if (pg_category == PG_U_UNASSIGNED &&
- pg_unicode_version < icu_unicode_version)
- pg_skipped_codepoints++;
- else if (icu_category == PG_U_UNASSIGNED &&
- icu_unicode_version < pg_unicode_version)
- icu_skipped_codepoints++;
- else
- {
- printf("category_test: FAILURE for codepoint 0x%06x\n", code);
- printf("category_test: Postgres category: %02d %s %s\n", pg_category,
- unicode_category_abbrev(pg_category),
- unicode_category_string(pg_category));
- printf("category_test: ICU category: %02d %s %s\n", icu_category,
- unicode_category_abbrev(icu_category),
- unicode_category_string(icu_category));
- printf("\n");
- exit(1);
- }
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres category: %02d %s %s\n", pg_category,
+ unicode_category_abbrev(pg_category),
+ unicode_category_string(pg_category));
+ printf("category_test: ICU category: %02d %s %s\n", icu_category,
+ unicode_category_abbrev(icu_category),
+ unicode_category_string(icu_category));
+ printf("\n");
+ exit(1);
}
+
+ if (prop_alphabetic != icu_prop_alphabetic ||
+ prop_lowercase != icu_prop_lowercase ||
+ prop_uppercase != icu_prop_uppercase ||
+ prop_cased != icu_prop_cased ||
+ prop_case_ignorable != icu_prop_case_ignorable ||
+ prop_white_space != icu_prop_white_space ||
+ prop_hex_digit != icu_prop_hex_digit ||
+ prop_join_control != icu_prop_join_control)
+ {
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres property alphabetic/lowercase/uppercase/cased/case_ignorable/white_space/hex_digit/join_control: %d/%d/%d/%d/%d/%d/%d/%d\n",
+ prop_alphabetic, prop_lowercase, prop_uppercase,
+ prop_cased, prop_case_ignorable,
+ prop_white_space, prop_hex_digit, prop_join_control);
+ printf("category_test: ICU property alphabetic/lowercase/uppercase/cased/case_ignorable/white_space/hex_digit/join_control: %d/%d/%d/%d/%d/%d/%d/%d\n",
+ icu_prop_alphabetic, icu_prop_lowercase, icu_prop_uppercase,
+ icu_prop_cased, icu_prop_case_ignorable,
+ icu_prop_white_space, icu_prop_hex_digit, icu_prop_join_control);
+ printf("\n");
+ exit(1);
+ }
+
+ if (isalpha != icu_isalpha ||
+ islower != icu_islower ||
+ isupper != icu_isupper ||
+ ispunct != icu_ispunct ||
+ isdigit != icu_isdigit ||
+ isxdigit != icu_isxdigit ||
+ isalnum != icu_isalnum ||
+ isspace != icu_isspace ||
+ isblank != icu_isblank ||
+ iscntrl != icu_iscntrl ||
+ isgraph != icu_isgraph ||
+ isprint != icu_isprint)
+ {
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres class alpha/lower/upper/punct/digit/xdigit/alnum/space/blank/cntrl/graph/print: %d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n",
+ isalpha, islower, isupper, ispunct, isdigit, isxdigit, isalnum, isspace, isblank, iscntrl, isgraph, isprint);
+ printf("category_test: ICU class alpha/lower/upper/punct/digit/xdigit/alnum/space/blank/cntrl/graph/print: %d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n",
+ icu_isalpha, icu_islower, icu_isupper, icu_ispunct, icu_isdigit, icu_isxdigit, icu_isalnum, icu_isspace, icu_isblank, icu_iscntrl, icu_isgraph, icu_isprint);
+ printf("\n");
+ exit(1);
+ }
+
+ if (pg_category != PG_U_UNASSIGNED)
+ successful++;
}
if (pg_skipped_codepoints > 0)
@@ -99,10 +222,22 @@ main(int argc, char **argv)
printf("category_test: skipped %d codepoints unassigned in ICU due to Unicode version mismatch\n",
icu_skipped_codepoints);
- printf("category_test: success\n");
- exit(0);
+ printf("category_test: ICU test: %d codepoints successful\n", successful);
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+ pg_unicode_version = parse_unicode_version(PG_UNICODE_VERSION);
+ printf("category_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
+
+#ifdef USE_ICU
+ icu_unicode_version = parse_unicode_version(U_UNICODE_VERSION);
+ printf("category_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
+
+ icu_test();
#else
- printf("category_test: ICU support required for test; skipping\n");
- exit(0);
+ printf("category_test: ICU not available; skipping\n");
#endif
}
diff --git a/src/common/unicode/generate-unicode_category_table.pl b/src/common/unicode/generate-unicode_category_table.pl
index a50c87b7e9..364e87201e 100644
--- a/src/common/unicode/generate-unicode_category_table.pl
+++ b/src/common/unicode/generate-unicode_category_table.pl
@@ -48,21 +48,30 @@ while (my $line = <$FH>)
my $category = $elts[2];
die "codepoint out of range" if $code > 0x10FFFF;
- die "unassigned codepoint in UnicodeData.txt" if $category eq $CATEGORY_UNASSIGNED;
+ die "unassigned codepoint in UnicodeData.txt"
+ if $category eq $CATEGORY_UNASSIGNED;
- if (!defined($range_start)) {
+ if (!defined($range_start))
+ {
my $code_str = sprintf "0x%06x", $code;
- die if defined($range_end) || defined($range_category) || defined($gap_category);
+ die
+ if defined($range_end)
+ || defined($range_category)
+ || defined($gap_category);
die "unexpected first entry <..., Last>" if ($name =~ /Last>/);
- die "expected 0x000000 for first entry, got $code_str" if $code != 0x000000;
+ die "expected 0x000000 for first entry, got $code_str"
+ if $code != 0x000000;
# initialize
$range_start = $code;
$range_end = $code;
$range_category = $category;
- if ($name =~ /<.*, First>$/) {
+ if ($name =~ /<.*, First>$/)
+ {
$gap_category = $category;
- } else {
+ }
+ else
+ {
$gap_category = $CATEGORY_UNASSIGNED;
}
next;
@@ -71,10 +80,17 @@ while (my $line = <$FH>)
# Gap in codepoints detected. If it's a different category than
# the current range, emit the current range and initialize a new
# range representing the gap.
- if ($range_end + 1 != $code && $range_category ne $gap_category) {
- if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+ if ($range_end + 1 != $code && $range_category ne $gap_category)
+ {
+ if ($range_category ne $CATEGORY_UNASSIGNED)
+ {
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
$range_start = $range_end + 1;
$range_end = $code - 1;
@@ -82,27 +98,39 @@ while (my $line = <$FH>)
}
# different category; new range
- if ($range_category ne $category) {
- if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+ if ($range_category ne $category)
+ {
+ if ($range_category ne $CATEGORY_UNASSIGNED)
+ {
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
$range_start = $code;
$range_end = $code;
$range_category = $category;
}
- if ($name =~ /<.*, First>$/) {
- die "<..., First> entry unexpectedly follows another <..., First> entry"
+ if ($name =~ /<.*, First>$/)
+ {
+ die
+ "<..., First> entry unexpectedly follows another <..., First> entry"
if $gap_category ne $CATEGORY_UNASSIGNED;
$gap_category = $category;
}
- elsif ($name =~ /<.*, Last>$/) {
- die "<..., First> and <..., Last> entries have mismatching general category"
+ elsif ($name =~ /<.*, Last>$/)
+ {
+ die
+ "<..., First> and <..., Last> entries have mismatching general category"
if $gap_category ne $category;
$gap_category = $CATEGORY_UNASSIGNED;
}
- else {
+ else
+ {
die "unexpected entry found between <..., First> and <..., Last>"
if $gap_category ne $CATEGORY_UNASSIGNED;
}
@@ -115,13 +143,17 @@ die "<..., First> entry with no corresponding <..., Last> entry"
if $gap_category ne $CATEGORY_UNASSIGNED;
# emit final range
-if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+if ($range_category ne $CATEGORY_UNASSIGNED)
+{
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
-my $num_ranges = scalar @category_ranges;
-
# See: https://www.unicode.org/reports/tr44/#General_Category_Values
my $categories = {
Cn => 'PG_U_UNASSIGNED',
@@ -156,11 +188,116 @@ my $categories = {
Pf => 'PG_U_FINAL_PUNCTUATION'
};
-# Start writing out the output files
+# Find White_Space and Hex_Digit characters
+my @white_space = ();
+my @hex_digits = ();
+my @join_control = ();
+open($FH, '<', "$output_path/PropList.txt")
+ or die "Could not open $output_path/PropList.txt: $!.";
+while (my $line = <$FH>)
+{
+ my $pattern = qr/([0-9A-F\.]+)\s*;\s*(\w+)\s*#.*/s;
+ next unless $line =~ $pattern;
+
+ my $code = $line =~ s/$pattern/$1/rg;
+ my $property = $line =~ s/$pattern/$2/rg;
+ my $start;
+ my $end;
+
+ if ($code =~ /\.\./)
+ {
+ # code range
+ my @sp = split /\.\./, $code;
+ $start = hex($sp[0]);
+ $end = hex($sp[1]);
+ }
+ else
+ {
+ # single code point
+ $start = hex($code);
+ $end = hex($code);
+ }
+
+ if ($property eq "White_Space")
+ {
+ push @white_space, { start => $start, end => $end };
+ }
+ elsif ($property eq "Hex_Digit")
+ {
+ push @hex_digits, { start => $start, end => $end };
+ }
+ elsif ($property eq "Join_Control")
+ {
+ push @join_control, { start => $start, end => $end };
+ }
+}
+
+# Find Alphabetic, Lowercase, and Uppercase characters
+my @alphabetic = ();
+my @lowercase = ();
+my @uppercase = ();
+my @case_ignorable = ();
+open($FH, '<', "$output_path/DerivedCoreProperties.txt")
+ or die "Could not open $output_path/DerivedCoreProperties.txt: $!.";
+while (my $line = <$FH>)
+{
+ my $pattern = qr/^([0-9A-F\.]+)\s*;\s*(\w+)\s*#.*$/s;
+ next unless $line =~ $pattern;
+
+ my $code = $line =~ s/$pattern/$1/rg;
+ my $property = $line =~ s/$pattern/$2/rg;
+ my $start;
+ my $end;
+
+ if ($code =~ /\.\./)
+ {
+ # code range
+ my @sp = split /\.\./, $code;
+ die "line: {$line} code: {$code} sp[0] {$sp[0]} sp[1] {$sp[1]}"
+ unless $sp[0] =~ /^[0-9A-F]+$/ && $sp[1] =~ /^[0-9A-F]+$/;
+ $start = hex($sp[0]);
+ $end = hex($sp[1]);
+ }
+ else
+ {
+ die "line: {$line} code: {$code}" unless $code =~ /^[0-9A-F]+$/;
+ # single code point
+ $start = hex($code);
+ $end = hex($code);
+ }
+
+ if ($property eq "Alphabetic")
+ {
+ push @alphabetic, { start => $start, end => $end };
+ }
+ elsif ($property eq "Lowercase")
+ {
+ push @lowercase, { start => $start, end => $end };
+ }
+ elsif ($property eq "Uppercase")
+ {
+ push @uppercase, { start => $start, end => $end };
+ }
+ elsif ($property eq "Case_Ignorable")
+ {
+ push @case_ignorable, { start => $start, end => $end };
+ }
+}
+
+my $num_category_ranges = scalar @category_ranges;
+my $num_alphabetic_ranges = scalar @alphabetic;
+my $num_lowercase_ranges = scalar @lowercase;
+my $num_uppercase_ranges = scalar @uppercase;
+my $num_case_ignorable_ranges = scalar @case_ignorable;
+my $num_white_space_ranges = scalar @white_space;
+my $num_hex_digit_ranges = scalar @hex_digits;
+my $num_join_control_ranges = scalar @join_control;
+
+# Start writing out the output file
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
-print $OT <<HEADER;
+print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
* unicode_category_table.h
@@ -188,18 +325,117 @@ typedef struct
uint8 category; /* General Category */
} pg_category_range;
-/* table of Unicode codepoint ranges and their categories */
-static const pg_category_range unicode_categories[$num_ranges] =
+typedef struct
{
-HEADER
+ uint32 first; /* Unicode codepoint */
+ uint32 last; /* Unicode codepoint */
+} pg_unicode_range;
-my $firsttime = 1;
-foreach my $range (@category_ranges) {
- printf $OT ",\n" unless $firsttime;
- $firsttime = 0;
+EOS
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges and their categories */
+static const pg_category_range unicode_categories[$num_category_ranges] =
+{
+EOS
- my $category = $categories->{$range->{category}};
+foreach my $range (@category_ranges)
+{
+ my $category = $categories->{ $range->{category} };
die "category missing: $range->{category}" unless $category;
- printf $OT "\t{0x%06x, 0x%06x, %s}", $range->{start}, $range->{end}, $category;
+ printf $OT "\t{0x%06x, 0x%06x, %s},\n", $range->{start}, $range->{end},
+ $category;
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Alphabetic characters */
+static const pg_unicode_range unicode_alphabetic[$num_alphabetic_ranges] =
+{
+EOS
+
+foreach my $range (@alphabetic)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Lowercase characters */
+static const pg_unicode_range unicode_lowercase[$num_lowercase_ranges] =
+{
+EOS
+
+foreach my $range (@lowercase)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Uppercase characters */
+static const pg_unicode_range unicode_uppercase[$num_uppercase_ranges] =
+{
+EOS
+
+foreach my $range (@uppercase)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Case_Ignorable characters */
+static const pg_unicode_range unicode_case_ignorable[$num_case_ignorable_ranges] =
+{
+EOS
+
+foreach my $range (@case_ignorable)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of White_Space characters */
+static const pg_unicode_range unicode_white_space[$num_white_space_ranges] =
+{
+EOS
+
+foreach my $range (@white_space)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Hex_Digit characters */
+static const pg_unicode_range unicode_hex_digit[$num_hex_digit_ranges] =
+{
+EOS
+
+foreach my $range (@hex_digits)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Join_Control characters */
+static const pg_unicode_range unicode_join_control[$num_join_control_ranges] =
+{
+EOS
+
+foreach my $range (@join_control)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
}
-print $OT "\n};\n";
+
+print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index df4f3a4ed1..d7190bb8ca 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_category_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['UnicodeData.txt'], unicode_data['DerivedCoreProperties.txt'], unicode_data['PropList.txt']],
output: ['unicode_category_table.h'],
command: [
perl, files('generate-unicode_category_table.pl'),
diff --git a/src/common/unicode_category.c b/src/common/unicode_category.c
index 668051b461..a37c52e204 100644
--- a/src/common/unicode_category.c
+++ b/src/common/unicode_category.c
@@ -1,6 +1,8 @@
/*-------------------------------------------------------------------------
* unicode_category.c
- * Determine general category of Unicode characters.
+ * Determine general category and character properties of Unicode
+ * characters. Encoding must be UTF8, where we assume that the pg_wchar
+ * representation is a code point.
*
* Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
*
@@ -18,24 +20,82 @@
#include "common/unicode_category.h"
#include "common/unicode_category_table.h"
+/*
+ * Create bitmasks from pg_unicode_category values for efficient comparison of
+ * multiple categories. For instance, PG_U_MN_MASK is a bitmask representing
+ * the general cateogry Mn; and PG_U_M_MASK represents general categories Mn,
+ * Me, and Mc.
+ *
+ * The number of Unicode General Categories should never grow, so a 32-bit
+ * mask is fine.
+ */
+#define PG_U_CATEGORY_MASK(X) ((uint32)(1 << (X)))
+
+#define PG_U_LU_MASK PG_U_CATEGORY_MASK(PG_U_UPPERCASE_LETTER)
+#define PG_U_LL_MASK PG_U_CATEGORY_MASK(PG_U_LOWERCASE_LETTER)
+#define PG_U_LT_MASK PG_U_CATEGORY_MASK(PG_U_TITLECASE_LETTER)
+#define PG_U_LC_MASK (PG_U_LU_MASK|PG_U_LL_MASK|PG_U_LT_MASK)
+#define PG_U_LM_MASK PG_U_CATEGORY_MASK(PG_U_MODIFIER_LETTER)
+#define PG_U_LO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_LETTER)
+#define PG_U_L_MASK (PG_U_LU_MASK|PG_U_LL_MASK|PG_U_LT_MASK|PG_U_LM_MASK|\
+ PG_U_LO_MASK)
+#define PG_U_MN_MASK PG_U_CATEGORY_MASK(PG_U_NONSPACING_MARK)
+#define PG_U_ME_MASK PG_U_CATEGORY_MASK(PG_U_ENCLOSING_MARK)
+#define PG_U_MC_MASK PG_U_CATEGORY_MASK(PG_U_SPACING_MARK)
+#define PG_U_M_MASK (PG_U_MN_MASK|PG_U_MC_MASK|PG_U_ME_MASK)
+#define PG_U_ND_MASK PG_U_CATEGORY_MASK(PG_U_DECIMAL_NUMBER)
+#define PG_U_NL_MASK PG_U_CATEGORY_MASK(PG_U_LETTER_NUMBER)
+#define PG_U_NO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_NUMBER)
+#define PG_U_N_MASK (PG_U_ND_MASK|PG_U_NL_MASK|PG_U_NO_MASK)
+#define PG_U_PC_MASK PG_U_CATEGORY_MASK(PG_U_CONNECTOR_PUNCTUATION)
+#define PG_U_PD_MASK PG_U_CATEGORY_MASK(PG_U_DASH_PUNCTUATION)
+#define PG_U_PS_MASK PG_U_CATEGORY_MASK(PG_U_OPEN_PUNCTUATION)
+#define PG_U_PE_MASK PG_U_CATEGORY_MASK(PG_U_CLOSE_PUNCTUATION)
+#define PG_U_PI_MASK PG_U_CATEGORY_MASK(PG_U_INITIAL_PUNCTUATION)
+#define PG_U_PF_MASK PG_U_CATEGORY_MASK(PG_U_FINAL_PUNCTUATION)
+#define PG_U_PO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_PUNCTUATION)
+#define PG_U_P_MASK (PG_U_PC_MASK|PG_U_PD_MASK|PG_U_PS_MASK|PG_U_PE_MASK|\
+ PG_U_PI_MASK|PG_U_PF_MASK|PG_U_PO_MASK)
+#define PG_U_SM_MASK PG_U_CATEGORY_MASK(PG_U_MATH_SYMBOL)
+#define PG_U_SC_MASK PG_U_CATEGORY_MASK(PG_U_CURRENCY_SYMBOL)
+#define PG_U_SK_MASK PG_U_CATEGORY_MASK(PG_U_MODIFIER_SYMBOL)
+#define PG_U_SO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_SYMBOL)
+#define PG_U_S_MASK (PG_U_SM_MASK|PG_U_SC_MASK|PG_U_SK_MASK|PG_U_SO_MASK)
+#define PG_U_ZS_MASK PG_U_CATEGORY_MASK(PG_U_SPACE_SEPARATOR)
+#define PG_U_ZL_MASK PG_U_CATEGORY_MASK(PG_U_LINE_SEPARATOR)
+#define PG_U_ZP_MASK PG_U_CATEGORY_MASK(PG_U_PARAGRAPH_SEPARATOR)
+#define PG_U_Z_MASK (PG_U_ZS_MASK|PG_U_ZL_MASK|PG_U_ZP_MASK)
+#define PG_U_CC_MASK PG_U_CATEGORY_MASK(PG_U_CONTROL)
+#define PG_U_CF_MASK PG_U_CATEGORY_MASK(PG_U_FORMAT)
+#define PG_U_CS_MASK PG_U_CATEGORY_MASK(PG_U_SURROGATE)
+#define PG_U_CO_MASK PG_U_CATEGORY_MASK(PG_U_PRIVATE_USE)
+#define PG_U_CN_MASK PG_U_CATEGORY_MASK(PG_U_UNASSIGNED)
+#define PG_U_C_MASK (PG_U_CC_MASK|PG_U_CF_MASK|PG_U_CS_MASK|PG_U_CO_MASK|\
+ PG_U_CN_MASK)
+
+#define PG_U_CHARACTER_TAB 0x09
+
+static bool range_search(const pg_unicode_range * tbl, size_t size,
+ pg_wchar code);
+
/*
* Unicode general category for the given codepoint.
*/
pg_unicode_category
-unicode_category(pg_wchar ucs)
+unicode_category(pg_wchar code)
{
int min = 0;
int mid;
int max = lengthof(unicode_categories) - 1;
- Assert(ucs <= 0x10ffff);
+ Assert(code <= 0x10ffff);
while (max >= min)
{
mid = (min + max) / 2;
- if (ucs > unicode_categories[mid].last)
+ if (code > unicode_categories[mid].last)
min = mid + 1;
- else if (ucs < unicode_categories[mid].first)
+ else if (code < unicode_categories[mid].first)
max = mid - 1;
else
return unicode_categories[mid].category;
@@ -44,6 +104,198 @@ unicode_category(pg_wchar ucs)
return PG_U_UNASSIGNED;
}
+bool
+pg_u_prop_alphabetic(pg_wchar code)
+{
+ return range_search(unicode_alphabetic,
+ lengthof(unicode_alphabetic),
+ code);
+}
+
+bool
+pg_u_prop_lowercase(pg_wchar code)
+{
+ return range_search(unicode_lowercase,
+ lengthof(unicode_lowercase),
+ code);
+}
+
+bool
+pg_u_prop_uppercase(pg_wchar code)
+{
+ return range_search(unicode_uppercase,
+ lengthof(unicode_uppercase),
+ code);
+}
+
+bool
+pg_u_prop_cased(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return category_mask & PG_U_LT_MASK ||
+ pg_u_prop_lowercase(code) ||
+ pg_u_prop_uppercase(code);
+}
+
+bool
+pg_u_prop_case_ignorable(pg_wchar code)
+{
+ return range_search(unicode_case_ignorable,
+ lengthof(unicode_case_ignorable),
+ code);
+}
+
+bool
+pg_u_prop_white_space(pg_wchar code)
+{
+ return range_search(unicode_white_space,
+ lengthof(unicode_white_space),
+ code);
+}
+
+bool
+pg_u_prop_hex_digit(pg_wchar code)
+{
+ return range_search(unicode_hex_digit,
+ lengthof(unicode_hex_digit),
+ code);
+}
+
+bool
+pg_u_prop_join_control(pg_wchar code)
+{
+ return range_search(unicode_join_control,
+ lengthof(unicode_join_control),
+ code);
+}
+
+/*
+ * The following functions implement the Compatibility Properties described
+ * at: http://www.unicode.org/reports/tr18/#Compatibility_Properties
+ *
+ * If 'posix' is true, implements the "POSIX Compatible" variant, otherwise
+ * the "Standard" variant.
+ */
+
+bool
+pg_u_isdigit(pg_wchar code, bool posix)
+{
+ if (posix)
+ return ('0' <= code && code <= '9');
+ else
+ return unicode_category(code) == PG_U_DECIMAL_NUMBER;
+}
+
+bool
+pg_u_isalpha(pg_wchar code)
+{
+ return pg_u_prop_alphabetic(code);
+}
+
+bool
+pg_u_isalnum(pg_wchar code, bool posix)
+{
+ return pg_u_isalpha(code) || pg_u_isdigit(code, posix);
+}
+
+bool
+pg_u_isword(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return
+ category_mask & (PG_U_M_MASK | PG_U_ND_MASK | PG_U_PC_MASK) ||
+ pg_u_isalpha(code) ||
+ pg_u_prop_join_control(code);
+}
+
+bool
+pg_u_isupper(pg_wchar code)
+{
+ return pg_u_prop_uppercase(code);
+}
+
+bool
+pg_u_islower(pg_wchar code)
+{
+ return pg_u_prop_lowercase(code);
+}
+
+bool
+pg_u_isblank(pg_wchar code)
+{
+ return code == PG_U_CHARACTER_TAB ||
+ unicode_category(code) == PG_U_SPACE_SEPARATOR;
+}
+
+bool
+pg_u_iscntrl(pg_wchar code)
+{
+ return unicode_category(code) == PG_U_CONTROL;
+}
+
+bool
+pg_u_isgraph(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ if (category_mask & (PG_U_CC_MASK | PG_U_CS_MASK | PG_U_CN_MASK) ||
+ pg_u_isspace(code))
+ return false;
+ return true;
+}
+
+bool
+pg_u_isprint(pg_wchar code)
+{
+ pg_unicode_category category = unicode_category(code);
+
+ if (category == PG_U_CONTROL)
+ return false;
+
+ return pg_u_isgraph(code) || pg_u_isblank(code);
+}
+
+bool
+pg_u_ispunct(pg_wchar code, bool posix)
+{
+ uint32 category_mask;
+
+ if (posix)
+ {
+ if (pg_u_isalpha(code))
+ return false;
+
+ category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+ return category_mask & (PG_U_P_MASK | PG_U_S_MASK);
+ }
+ else
+ {
+ category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return category_mask & PG_U_P_MASK;
+ }
+}
+
+bool
+pg_u_isspace(pg_wchar code)
+{
+ return pg_u_prop_white_space(code);
+}
+
+bool
+pg_u_isxdigit(pg_wchar code, bool posix)
+{
+ if (posix)
+ return (('0' <= code && code <= '9') ||
+ ('A' <= code && code <= 'F') ||
+ ('a' <= code && code <= 'f'));
+ else
+ return unicode_category(code) == PG_U_DECIMAL_NUMBER ||
+ pg_u_prop_hex_digit(code);
+}
+
/*
* Description of Unicode general category.
*/
@@ -191,3 +443,30 @@ unicode_category_abbrev(pg_unicode_category category)
Assert(false);
return "??"; /* keep compiler quiet */
}
+
+/*
+ * Binary search to test if given codepoint exists in one of the ranges in the
+ * given table.
+ */
+static bool
+range_search(const pg_unicode_range * tbl, size_t size, pg_wchar code)
+{
+ int min = 0;
+ int mid;
+ int max = size - 1;
+
+ Assert(code <= 0x10ffff);
+
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (code > tbl[mid].last)
+ min = mid + 1;
+ else if (code < tbl[mid].first)
+ max = mid - 1;
+ else
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/include/common/unicode_category.h b/src/include/common/unicode_category.h
index 5bad280615..f185b58900 100644
--- a/src/include/common/unicode_category.h
+++ b/src/include/common/unicode_category.h
@@ -62,7 +62,30 @@ typedef enum pg_unicode_category
} pg_unicode_category;
extern pg_unicode_category unicode_category(pg_wchar ucs);
-const char *unicode_category_string(pg_unicode_category category);
-const char *unicode_category_abbrev(pg_unicode_category category);
+extern const char *unicode_category_string(pg_unicode_category category);
+extern const char *unicode_category_abbrev(pg_unicode_category category);
+
+extern bool pg_u_prop_alphabetic(pg_wchar c);
+extern bool pg_u_prop_lowercase(pg_wchar c);
+extern bool pg_u_prop_uppercase(pg_wchar c);
+extern bool pg_u_prop_cased(pg_wchar c);
+extern bool pg_u_prop_case_ignorable(pg_wchar c);
+extern bool pg_u_prop_white_space(pg_wchar c);
+extern bool pg_u_prop_hex_digit(pg_wchar c);
+extern bool pg_u_prop_join_control(pg_wchar c);
+
+extern bool pg_u_isdigit(pg_wchar c, bool posix);
+extern bool pg_u_isalpha(pg_wchar c);
+extern bool pg_u_isalnum(pg_wchar c, bool posix);
+extern bool pg_u_isword(pg_wchar c);
+extern bool pg_u_isupper(pg_wchar c);
+extern bool pg_u_islower(pg_wchar c);
+extern bool pg_u_isblank(pg_wchar c);
+extern bool pg_u_iscntrl(pg_wchar c);
+extern bool pg_u_isgraph(pg_wchar c);
+extern bool pg_u_isprint(pg_wchar c);
+extern bool pg_u_ispunct(pg_wchar c, bool posix);
+extern bool pg_u_isspace(pg_wchar c);
+extern bool pg_u_isxdigit(pg_wchar c, bool posix);
#endif /* UNICODE_CATEGORY_H */
diff --git a/src/include/common/unicode_category_table.h b/src/include/common/unicode_category_table.h
index d7ef996189..3bede82f20 100644
--- a/src/include/common/unicode_category_table.h
+++ b/src/include/common/unicode_category_table.h
@@ -25,6 +25,12 @@ typedef struct
uint8 category; /* General Category */
} pg_category_range;
+typedef struct
+{
+ uint32 first; /* Unicode codepoint */
+ uint32 last; /* Unicode codepoint */
+} pg_unicode_range;
+
/* table of Unicode codepoint ranges and their categories */
static const pg_category_range unicode_categories[3302] =
{
@@ -3329,5 +3335,3027 @@ static const pg_category_range unicode_categories[3302] =
{0x0e0020, 0x0e007f, PG_U_FORMAT},
{0x0e0100, 0x0e01ef, PG_U_NONSPACING_MARK},
{0x0f0000, 0x0ffffd, PG_U_PRIVATE_USE},
- {0x100000, 0x10fffd, PG_U_PRIVATE_USE}
+ {0x100000, 0x10fffd, PG_U_PRIVATE_USE},
+};
+
+/* table of Unicode codepoint ranges of Alphabetic characters */
+static const pg_unicode_range unicode_alphabetic[1141] =
+{
+ {0x000041, 0x00005a},
+ {0x000061, 0x00007a},
+ {0x0000aa, 0x0000aa},
+ {0x0000b5, 0x0000b5},
+ {0x0000ba, 0x0000ba},
+ {0x0000c0, 0x0000d6},
+ {0x0000d8, 0x0000f6},
+ {0x0000f8, 0x0001ba},
+ {0x0001bb, 0x0001bb},
+ {0x0001bc, 0x0001bf},
+ {0x0001c0, 0x0001c3},
+ {0x0001c4, 0x000293},
+ {0x000294, 0x000294},
+ {0x000295, 0x0002af},
+ {0x0002b0, 0x0002c1},
+ {0x0002c6, 0x0002d1},
+ {0x0002e0, 0x0002e4},
+ {0x0002ec, 0x0002ec},
+ {0x0002ee, 0x0002ee},
+ {0x000345, 0x000345},
+ {0x000370, 0x000373},
+ {0x000374, 0x000374},
+ {0x000376, 0x000377},
+ {0x00037a, 0x00037a},
+ {0x00037b, 0x00037d},
+ {0x00037f, 0x00037f},
+ {0x000386, 0x000386},
+ {0x000388, 0x00038a},
+ {0x00038c, 0x00038c},
+ {0x00038e, 0x0003a1},
+ {0x0003a3, 0x0003f5},
+ {0x0003f7, 0x000481},
+ {0x00048a, 0x00052f},
+ {0x000531, 0x000556},
+ {0x000559, 0x000559},
+ {0x000560, 0x000588},
+ {0x0005b0, 0x0005bd},
+ {0x0005bf, 0x0005bf},
+ {0x0005c1, 0x0005c2},
+ {0x0005c4, 0x0005c5},
+ {0x0005c7, 0x0005c7},
+ {0x0005d0, 0x0005ea},
+ {0x0005ef, 0x0005f2},
+ {0x000610, 0x00061a},
+ {0x000620, 0x00063f},
+ {0x000640, 0x000640},
+ {0x000641, 0x00064a},
+ {0x00064b, 0x000657},
+ {0x000659, 0x00065f},
+ {0x00066e, 0x00066f},
+ {0x000670, 0x000670},
+ {0x000671, 0x0006d3},
+ {0x0006d5, 0x0006d5},
+ {0x0006d6, 0x0006dc},
+ {0x0006e1, 0x0006e4},
+ {0x0006e5, 0x0006e6},
+ {0x0006e7, 0x0006e8},
+ {0x0006ed, 0x0006ed},
+ {0x0006ee, 0x0006ef},
+ {0x0006fa, 0x0006fc},
+ {0x0006ff, 0x0006ff},
+ {0x000710, 0x000710},
+ {0x000711, 0x000711},
+ {0x000712, 0x00072f},
+ {0x000730, 0x00073f},
+ {0x00074d, 0x0007a5},
+ {0x0007a6, 0x0007b0},
+ {0x0007b1, 0x0007b1},
+ {0x0007ca, 0x0007ea},
+ {0x0007f4, 0x0007f5},
+ {0x0007fa, 0x0007fa},
+ {0x000800, 0x000815},
+ {0x000816, 0x000817},
+ {0x00081a, 0x00081a},
+ {0x00081b, 0x000823},
+ {0x000824, 0x000824},
+ {0x000825, 0x000827},
+ {0x000828, 0x000828},
+ {0x000829, 0x00082c},
+ {0x000840, 0x000858},
+ {0x000860, 0x00086a},
+ {0x000870, 0x000887},
+ {0x000889, 0x00088e},
+ {0x0008a0, 0x0008c8},
+ {0x0008c9, 0x0008c9},
+ {0x0008d4, 0x0008df},
+ {0x0008e3, 0x0008e9},
+ {0x0008f0, 0x000902},
+ {0x000903, 0x000903},
+ {0x000904, 0x000939},
+ {0x00093a, 0x00093a},
+ {0x00093b, 0x00093b},
+ {0x00093d, 0x00093d},
+ {0x00093e, 0x000940},
+ {0x000941, 0x000948},
+ {0x000949, 0x00094c},
+ {0x00094e, 0x00094f},
+ {0x000950, 0x000950},
+ {0x000955, 0x000957},
+ {0x000958, 0x000961},
+ {0x000962, 0x000963},
+ {0x000971, 0x000971},
+ {0x000972, 0x000980},
+ {0x000981, 0x000981},
+ {0x000982, 0x000983},
+ {0x000985, 0x00098c},
+ {0x00098f, 0x000990},
+ {0x000993, 0x0009a8},
+ {0x0009aa, 0x0009b0},
+ {0x0009b2, 0x0009b2},
+ {0x0009b6, 0x0009b9},
+ {0x0009bd, 0x0009bd},
+ {0x0009be, 0x0009c0},
+ {0x0009c1, 0x0009c4},
+ {0x0009c7, 0x0009c8},
+ {0x0009cb, 0x0009cc},
+ {0x0009ce, 0x0009ce},
+ {0x0009d7, 0x0009d7},
+ {0x0009dc, 0x0009dd},
+ {0x0009df, 0x0009e1},
+ {0x0009e2, 0x0009e3},
+ {0x0009f0, 0x0009f1},
+ {0x0009fc, 0x0009fc},
+ {0x000a01, 0x000a02},
+ {0x000a03, 0x000a03},
+ {0x000a05, 0x000a0a},
+ {0x000a0f, 0x000a10},
+ {0x000a13, 0x000a28},
+ {0x000a2a, 0x000a30},
+ {0x000a32, 0x000a33},
+ {0x000a35, 0x000a36},
+ {0x000a38, 0x000a39},
+ {0x000a3e, 0x000a40},
+ {0x000a41, 0x000a42},
+ {0x000a47, 0x000a48},
+ {0x000a4b, 0x000a4c},
+ {0x000a51, 0x000a51},
+ {0x000a59, 0x000a5c},
+ {0x000a5e, 0x000a5e},
+ {0x000a70, 0x000a71},
+ {0x000a72, 0x000a74},
+ {0x000a75, 0x000a75},
+ {0x000a81, 0x000a82},
+ {0x000a83, 0x000a83},
+ {0x000a85, 0x000a8d},
+ {0x000a8f, 0x000a91},
+ {0x000a93, 0x000aa8},
+ {0x000aaa, 0x000ab0},
+ {0x000ab2, 0x000ab3},
+ {0x000ab5, 0x000ab9},
+ {0x000abd, 0x000abd},
+ {0x000abe, 0x000ac0},
+ {0x000ac1, 0x000ac5},
+ {0x000ac7, 0x000ac8},
+ {0x000ac9, 0x000ac9},
+ {0x000acb, 0x000acc},
+ {0x000ad0, 0x000ad0},
+ {0x000ae0, 0x000ae1},
+ {0x000ae2, 0x000ae3},
+ {0x000af9, 0x000af9},
+ {0x000afa, 0x000afc},
+ {0x000b01, 0x000b01},
+ {0x000b02, 0x000b03},
+ {0x000b05, 0x000b0c},
+ {0x000b0f, 0x000b10},
+ {0x000b13, 0x000b28},
+ {0x000b2a, 0x000b30},
+ {0x000b32, 0x000b33},
+ {0x000b35, 0x000b39},
+ {0x000b3d, 0x000b3d},
+ {0x000b3e, 0x000b3e},
+ {0x000b3f, 0x000b3f},
+ {0x000b40, 0x000b40},
+ {0x000b41, 0x000b44},
+ {0x000b47, 0x000b48},
+ {0x000b4b, 0x000b4c},
+ {0x000b56, 0x000b56},
+ {0x000b57, 0x000b57},
+ {0x000b5c, 0x000b5d},
+ {0x000b5f, 0x000b61},
+ {0x000b62, 0x000b63},
+ {0x000b71, 0x000b71},
+ {0x000b82, 0x000b82},
+ {0x000b83, 0x000b83},
+ {0x000b85, 0x000b8a},
+ {0x000b8e, 0x000b90},
+ {0x000b92, 0x000b95},
+ {0x000b99, 0x000b9a},
+ {0x000b9c, 0x000b9c},
+ {0x000b9e, 0x000b9f},
+ {0x000ba3, 0x000ba4},
+ {0x000ba8, 0x000baa},
+ {0x000bae, 0x000bb9},
+ {0x000bbe, 0x000bbf},
+ {0x000bc0, 0x000bc0},
+ {0x000bc1, 0x000bc2},
+ {0x000bc6, 0x000bc8},
+ {0x000bca, 0x000bcc},
+ {0x000bd0, 0x000bd0},
+ {0x000bd7, 0x000bd7},
+ {0x000c00, 0x000c00},
+ {0x000c01, 0x000c03},
+ {0x000c04, 0x000c04},
+ {0x000c05, 0x000c0c},
+ {0x000c0e, 0x000c10},
+ {0x000c12, 0x000c28},
+ {0x000c2a, 0x000c39},
+ {0x000c3d, 0x000c3d},
+ {0x000c3e, 0x000c40},
+ {0x000c41, 0x000c44},
+ {0x000c46, 0x000c48},
+ {0x000c4a, 0x000c4c},
+ {0x000c55, 0x000c56},
+ {0x000c58, 0x000c5a},
+ {0x000c5d, 0x000c5d},
+ {0x000c60, 0x000c61},
+ {0x000c62, 0x000c63},
+ {0x000c80, 0x000c80},
+ {0x000c81, 0x000c81},
+ {0x000c82, 0x000c83},
+ {0x000c85, 0x000c8c},
+ {0x000c8e, 0x000c90},
+ {0x000c92, 0x000ca8},
+ {0x000caa, 0x000cb3},
+ {0x000cb5, 0x000cb9},
+ {0x000cbd, 0x000cbd},
+ {0x000cbe, 0x000cbe},
+ {0x000cbf, 0x000cbf},
+ {0x000cc0, 0x000cc4},
+ {0x000cc6, 0x000cc6},
+ {0x000cc7, 0x000cc8},
+ {0x000cca, 0x000ccb},
+ {0x000ccc, 0x000ccc},
+ {0x000cd5, 0x000cd6},
+ {0x000cdd, 0x000cde},
+ {0x000ce0, 0x000ce1},
+ {0x000ce2, 0x000ce3},
+ {0x000cf1, 0x000cf2},
+ {0x000cf3, 0x000cf3},
+ {0x000d00, 0x000d01},
+ {0x000d02, 0x000d03},
+ {0x000d04, 0x000d0c},
+ {0x000d0e, 0x000d10},
+ {0x000d12, 0x000d3a},
+ {0x000d3d, 0x000d3d},
+ {0x000d3e, 0x000d40},
+ {0x000d41, 0x000d44},
+ {0x000d46, 0x000d48},
+ {0x000d4a, 0x000d4c},
+ {0x000d4e, 0x000d4e},
+ {0x000d54, 0x000d56},
+ {0x000d57, 0x000d57},
+ {0x000d5f, 0x000d61},
+ {0x000d62, 0x000d63},
+ {0x000d7a, 0x000d7f},
+ {0x000d81, 0x000d81},
+ {0x000d82, 0x000d83},
+ {0x000d85, 0x000d96},
+ {0x000d9a, 0x000db1},
+ {0x000db3, 0x000dbb},
+ {0x000dbd, 0x000dbd},
+ {0x000dc0, 0x000dc6},
+ {0x000dcf, 0x000dd1},
+ {0x000dd2, 0x000dd4},
+ {0x000dd6, 0x000dd6},
+ {0x000dd8, 0x000ddf},
+ {0x000df2, 0x000df3},
+ {0x000e01, 0x000e30},
+ {0x000e31, 0x000e31},
+ {0x000e32, 0x000e33},
+ {0x000e34, 0x000e3a},
+ {0x000e40, 0x000e45},
+ {0x000e46, 0x000e46},
+ {0x000e4d, 0x000e4d},
+ {0x000e81, 0x000e82},
+ {0x000e84, 0x000e84},
+ {0x000e86, 0x000e8a},
+ {0x000e8c, 0x000ea3},
+ {0x000ea5, 0x000ea5},
+ {0x000ea7, 0x000eb0},
+ {0x000eb1, 0x000eb1},
+ {0x000eb2, 0x000eb3},
+ {0x000eb4, 0x000eb9},
+ {0x000ebb, 0x000ebc},
+ {0x000ebd, 0x000ebd},
+ {0x000ec0, 0x000ec4},
+ {0x000ec6, 0x000ec6},
+ {0x000ecd, 0x000ecd},
+ {0x000edc, 0x000edf},
+ {0x000f00, 0x000f00},
+ {0x000f40, 0x000f47},
+ {0x000f49, 0x000f6c},
+ {0x000f71, 0x000f7e},
+ {0x000f7f, 0x000f7f},
+ {0x000f80, 0x000f83},
+ {0x000f88, 0x000f8c},
+ {0x000f8d, 0x000f97},
+ {0x000f99, 0x000fbc},
+ {0x001000, 0x00102a},
+ {0x00102b, 0x00102c},
+ {0x00102d, 0x001030},
+ {0x001031, 0x001031},
+ {0x001032, 0x001036},
+ {0x001038, 0x001038},
+ {0x00103b, 0x00103c},
+ {0x00103d, 0x00103e},
+ {0x00103f, 0x00103f},
+ {0x001050, 0x001055},
+ {0x001056, 0x001057},
+ {0x001058, 0x001059},
+ {0x00105a, 0x00105d},
+ {0x00105e, 0x001060},
+ {0x001061, 0x001061},
+ {0x001062, 0x001064},
+ {0x001065, 0x001066},
+ {0x001067, 0x00106d},
+ {0x00106e, 0x001070},
+ {0x001071, 0x001074},
+ {0x001075, 0x001081},
+ {0x001082, 0x001082},
+ {0x001083, 0x001084},
+ {0x001085, 0x001086},
+ {0x001087, 0x00108c},
+ {0x00108d, 0x00108d},
+ {0x00108e, 0x00108e},
+ {0x00108f, 0x00108f},
+ {0x00109a, 0x00109c},
+ {0x00109d, 0x00109d},
+ {0x0010a0, 0x0010c5},
+ {0x0010c7, 0x0010c7},
+ {0x0010cd, 0x0010cd},
+ {0x0010d0, 0x0010fa},
+ {0x0010fc, 0x0010fc},
+ {0x0010fd, 0x0010ff},
+ {0x001100, 0x001248},
+ {0x00124a, 0x00124d},
+ {0x001250, 0x001256},
+ {0x001258, 0x001258},
+ {0x00125a, 0x00125d},
+ {0x001260, 0x001288},
+ {0x00128a, 0x00128d},
+ {0x001290, 0x0012b0},
+ {0x0012b2, 0x0012b5},
+ {0x0012b8, 0x0012be},
+ {0x0012c0, 0x0012c0},
+ {0x0012c2, 0x0012c5},
+ {0x0012c8, 0x0012d6},
+ {0x0012d8, 0x001310},
+ {0x001312, 0x001315},
+ {0x001318, 0x00135a},
+ {0x001380, 0x00138f},
+ {0x0013a0, 0x0013f5},
+ {0x0013f8, 0x0013fd},
+ {0x001401, 0x00166c},
+ {0x00166f, 0x00167f},
+ {0x001681, 0x00169a},
+ {0x0016a0, 0x0016ea},
+ {0x0016ee, 0x0016f0},
+ {0x0016f1, 0x0016f8},
+ {0x001700, 0x001711},
+ {0x001712, 0x001713},
+ {0x00171f, 0x001731},
+ {0x001732, 0x001733},
+ {0x001740, 0x001751},
+ {0x001752, 0x001753},
+ {0x001760, 0x00176c},
+ {0x00176e, 0x001770},
+ {0x001772, 0x001773},
+ {0x001780, 0x0017b3},
+ {0x0017b6, 0x0017b6},
+ {0x0017b7, 0x0017bd},
+ {0x0017be, 0x0017c5},
+ {0x0017c6, 0x0017c6},
+ {0x0017c7, 0x0017c8},
+ {0x0017d7, 0x0017d7},
+ {0x0017dc, 0x0017dc},
+ {0x001820, 0x001842},
+ {0x001843, 0x001843},
+ {0x001844, 0x001878},
+ {0x001880, 0x001884},
+ {0x001885, 0x001886},
+ {0x001887, 0x0018a8},
+ {0x0018a9, 0x0018a9},
+ {0x0018aa, 0x0018aa},
+ {0x0018b0, 0x0018f5},
+ {0x001900, 0x00191e},
+ {0x001920, 0x001922},
+ {0x001923, 0x001926},
+ {0x001927, 0x001928},
+ {0x001929, 0x00192b},
+ {0x001930, 0x001931},
+ {0x001932, 0x001932},
+ {0x001933, 0x001938},
+ {0x001950, 0x00196d},
+ {0x001970, 0x001974},
+ {0x001980, 0x0019ab},
+ {0x0019b0, 0x0019c9},
+ {0x001a00, 0x001a16},
+ {0x001a17, 0x001a18},
+ {0x001a19, 0x001a1a},
+ {0x001a1b, 0x001a1b},
+ {0x001a20, 0x001a54},
+ {0x001a55, 0x001a55},
+ {0x001a56, 0x001a56},
+ {0x001a57, 0x001a57},
+ {0x001a58, 0x001a5e},
+ {0x001a61, 0x001a61},
+ {0x001a62, 0x001a62},
+ {0x001a63, 0x001a64},
+ {0x001a65, 0x001a6c},
+ {0x001a6d, 0x001a72},
+ {0x001a73, 0x001a74},
+ {0x001aa7, 0x001aa7},
+ {0x001abf, 0x001ac0},
+ {0x001acc, 0x001ace},
+ {0x001b00, 0x001b03},
+ {0x001b04, 0x001b04},
+ {0x001b05, 0x001b33},
+ {0x001b35, 0x001b35},
+ {0x001b36, 0x001b3a},
+ {0x001b3b, 0x001b3b},
+ {0x001b3c, 0x001b3c},
+ {0x001b3d, 0x001b41},
+ {0x001b42, 0x001b42},
+ {0x001b43, 0x001b43},
+ {0x001b45, 0x001b4c},
+ {0x001b80, 0x001b81},
+ {0x001b82, 0x001b82},
+ {0x001b83, 0x001ba0},
+ {0x001ba1, 0x001ba1},
+ {0x001ba2, 0x001ba5},
+ {0x001ba6, 0x001ba7},
+ {0x001ba8, 0x001ba9},
+ {0x001bac, 0x001bad},
+ {0x001bae, 0x001baf},
+ {0x001bba, 0x001be5},
+ {0x001be7, 0x001be7},
+ {0x001be8, 0x001be9},
+ {0x001bea, 0x001bec},
+ {0x001bed, 0x001bed},
+ {0x001bee, 0x001bee},
+ {0x001bef, 0x001bf1},
+ {0x001c00, 0x001c23},
+ {0x001c24, 0x001c2b},
+ {0x001c2c, 0x001c33},
+ {0x001c34, 0x001c35},
+ {0x001c36, 0x001c36},
+ {0x001c4d, 0x001c4f},
+ {0x001c5a, 0x001c77},
+ {0x001c78, 0x001c7d},
+ {0x001c80, 0x001c88},
+ {0x001c90, 0x001cba},
+ {0x001cbd, 0x001cbf},
+ {0x001ce9, 0x001cec},
+ {0x001cee, 0x001cf3},
+ {0x001cf5, 0x001cf6},
+ {0x001cfa, 0x001cfa},
+ {0x001d00, 0x001d2b},
+ {0x001d2c, 0x001d6a},
+ {0x001d6b, 0x001d77},
+ {0x001d78, 0x001d78},
+ {0x001d79, 0x001d9a},
+ {0x001d9b, 0x001dbf},
+ {0x001de7, 0x001df4},
+ {0x001e00, 0x001f15},
+ {0x001f18, 0x001f1d},
+ {0x001f20, 0x001f45},
+ {0x001f48, 0x001f4d},
+ {0x001f50, 0x001f57},
+ {0x001f59, 0x001f59},
+ {0x001f5b, 0x001f5b},
+ {0x001f5d, 0x001f5d},
+ {0x001f5f, 0x001f7d},
+ {0x001f80, 0x001fb4},
+ {0x001fb6, 0x001fbc},
+ {0x001fbe, 0x001fbe},
+ {0x001fc2, 0x001fc4},
+ {0x001fc6, 0x001fcc},
+ {0x001fd0, 0x001fd3},
+ {0x001fd6, 0x001fdb},
+ {0x001fe0, 0x001fec},
+ {0x001ff2, 0x001ff4},
+ {0x001ff6, 0x001ffc},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x002102, 0x002102},
+ {0x002107, 0x002107},
+ {0x00210a, 0x002113},
+ {0x002115, 0x002115},
+ {0x002119, 0x00211d},
+ {0x002124, 0x002124},
+ {0x002126, 0x002126},
+ {0x002128, 0x002128},
+ {0x00212a, 0x00212d},
+ {0x00212f, 0x002134},
+ {0x002135, 0x002138},
+ {0x002139, 0x002139},
+ {0x00213c, 0x00213f},
+ {0x002145, 0x002149},
+ {0x00214e, 0x00214e},
+ {0x002160, 0x002182},
+ {0x002183, 0x002184},
+ {0x002185, 0x002188},
+ {0x0024b6, 0x0024e9},
+ {0x002c00, 0x002c7b},
+ {0x002c7c, 0x002c7d},
+ {0x002c7e, 0x002ce4},
+ {0x002ceb, 0x002cee},
+ {0x002cf2, 0x002cf3},
+ {0x002d00, 0x002d25},
+ {0x002d27, 0x002d27},
+ {0x002d2d, 0x002d2d},
+ {0x002d30, 0x002d67},
+ {0x002d6f, 0x002d6f},
+ {0x002d80, 0x002d96},
+ {0x002da0, 0x002da6},
+ {0x002da8, 0x002dae},
+ {0x002db0, 0x002db6},
+ {0x002db8, 0x002dbe},
+ {0x002dc0, 0x002dc6},
+ {0x002dc8, 0x002dce},
+ {0x002dd0, 0x002dd6},
+ {0x002dd8, 0x002dde},
+ {0x002de0, 0x002dff},
+ {0x002e2f, 0x002e2f},
+ {0x003005, 0x003005},
+ {0x003006, 0x003006},
+ {0x003007, 0x003007},
+ {0x003021, 0x003029},
+ {0x003031, 0x003035},
+ {0x003038, 0x00303a},
+ {0x00303b, 0x00303b},
+ {0x00303c, 0x00303c},
+ {0x003041, 0x003096},
+ {0x00309d, 0x00309e},
+ {0x00309f, 0x00309f},
+ {0x0030a1, 0x0030fa},
+ {0x0030fc, 0x0030fe},
+ {0x0030ff, 0x0030ff},
+ {0x003105, 0x00312f},
+ {0x003131, 0x00318e},
+ {0x0031a0, 0x0031bf},
+ {0x0031f0, 0x0031ff},
+ {0x003400, 0x004dbf},
+ {0x004e00, 0x00a014},
+ {0x00a015, 0x00a015},
+ {0x00a016, 0x00a48c},
+ {0x00a4d0, 0x00a4f7},
+ {0x00a4f8, 0x00a4fd},
+ {0x00a500, 0x00a60b},
+ {0x00a60c, 0x00a60c},
+ {0x00a610, 0x00a61f},
+ {0x00a62a, 0x00a62b},
+ {0x00a640, 0x00a66d},
+ {0x00a66e, 0x00a66e},
+ {0x00a674, 0x00a67b},
+ {0x00a67f, 0x00a67f},
+ {0x00a680, 0x00a69b},
+ {0x00a69c, 0x00a69d},
+ {0x00a69e, 0x00a69f},
+ {0x00a6a0, 0x00a6e5},
+ {0x00a6e6, 0x00a6ef},
+ {0x00a717, 0x00a71f},
+ {0x00a722, 0x00a76f},
+ {0x00a770, 0x00a770},
+ {0x00a771, 0x00a787},
+ {0x00a788, 0x00a788},
+ {0x00a78b, 0x00a78e},
+ {0x00a78f, 0x00a78f},
+ {0x00a790, 0x00a7ca},
+ {0x00a7d0, 0x00a7d1},
+ {0x00a7d3, 0x00a7d3},
+ {0x00a7d5, 0x00a7d9},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f5, 0x00a7f6},
+ {0x00a7f7, 0x00a7f7},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a7fa, 0x00a7fa},
+ {0x00a7fb, 0x00a801},
+ {0x00a802, 0x00a802},
+ {0x00a803, 0x00a805},
+ {0x00a807, 0x00a80a},
+ {0x00a80b, 0x00a80b},
+ {0x00a80c, 0x00a822},
+ {0x00a823, 0x00a824},
+ {0x00a825, 0x00a826},
+ {0x00a827, 0x00a827},
+ {0x00a840, 0x00a873},
+ {0x00a880, 0x00a881},
+ {0x00a882, 0x00a8b3},
+ {0x00a8b4, 0x00a8c3},
+ {0x00a8c5, 0x00a8c5},
+ {0x00a8f2, 0x00a8f7},
+ {0x00a8fb, 0x00a8fb},
+ {0x00a8fd, 0x00a8fe},
+ {0x00a8ff, 0x00a8ff},
+ {0x00a90a, 0x00a925},
+ {0x00a926, 0x00a92a},
+ {0x00a930, 0x00a946},
+ {0x00a947, 0x00a951},
+ {0x00a952, 0x00a952},
+ {0x00a960, 0x00a97c},
+ {0x00a980, 0x00a982},
+ {0x00a983, 0x00a983},
+ {0x00a984, 0x00a9b2},
+ {0x00a9b4, 0x00a9b5},
+ {0x00a9b6, 0x00a9b9},
+ {0x00a9ba, 0x00a9bb},
+ {0x00a9bc, 0x00a9bd},
+ {0x00a9be, 0x00a9bf},
+ {0x00a9cf, 0x00a9cf},
+ {0x00a9e0, 0x00a9e4},
+ {0x00a9e5, 0x00a9e5},
+ {0x00a9e6, 0x00a9e6},
+ {0x00a9e7, 0x00a9ef},
+ {0x00a9fa, 0x00a9fe},
+ {0x00aa00, 0x00aa28},
+ {0x00aa29, 0x00aa2e},
+ {0x00aa2f, 0x00aa30},
+ {0x00aa31, 0x00aa32},
+ {0x00aa33, 0x00aa34},
+ {0x00aa35, 0x00aa36},
+ {0x00aa40, 0x00aa42},
+ {0x00aa43, 0x00aa43},
+ {0x00aa44, 0x00aa4b},
+ {0x00aa4c, 0x00aa4c},
+ {0x00aa4d, 0x00aa4d},
+ {0x00aa60, 0x00aa6f},
+ {0x00aa70, 0x00aa70},
+ {0x00aa71, 0x00aa76},
+ {0x00aa7a, 0x00aa7a},
+ {0x00aa7b, 0x00aa7b},
+ {0x00aa7c, 0x00aa7c},
+ {0x00aa7d, 0x00aa7d},
+ {0x00aa7e, 0x00aaaf},
+ {0x00aab0, 0x00aab0},
+ {0x00aab1, 0x00aab1},
+ {0x00aab2, 0x00aab4},
+ {0x00aab5, 0x00aab6},
+ {0x00aab7, 0x00aab8},
+ {0x00aab9, 0x00aabd},
+ {0x00aabe, 0x00aabe},
+ {0x00aac0, 0x00aac0},
+ {0x00aac2, 0x00aac2},
+ {0x00aadb, 0x00aadc},
+ {0x00aadd, 0x00aadd},
+ {0x00aae0, 0x00aaea},
+ {0x00aaeb, 0x00aaeb},
+ {0x00aaec, 0x00aaed},
+ {0x00aaee, 0x00aaef},
+ {0x00aaf2, 0x00aaf2},
+ {0x00aaf3, 0x00aaf4},
+ {0x00aaf5, 0x00aaf5},
+ {0x00ab01, 0x00ab06},
+ {0x00ab09, 0x00ab0e},
+ {0x00ab11, 0x00ab16},
+ {0x00ab20, 0x00ab26},
+ {0x00ab28, 0x00ab2e},
+ {0x00ab30, 0x00ab5a},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab60, 0x00ab68},
+ {0x00ab69, 0x00ab69},
+ {0x00ab70, 0x00abbf},
+ {0x00abc0, 0x00abe2},
+ {0x00abe3, 0x00abe4},
+ {0x00abe5, 0x00abe5},
+ {0x00abe6, 0x00abe7},
+ {0x00abe8, 0x00abe8},
+ {0x00abe9, 0x00abea},
+ {0x00ac00, 0x00d7a3},
+ {0x00d7b0, 0x00d7c6},
+ {0x00d7cb, 0x00d7fb},
+ {0x00f900, 0x00fa6d},
+ {0x00fa70, 0x00fad9},
+ {0x00fb00, 0x00fb06},
+ {0x00fb13, 0x00fb17},
+ {0x00fb1d, 0x00fb1d},
+ {0x00fb1e, 0x00fb1e},
+ {0x00fb1f, 0x00fb28},
+ {0x00fb2a, 0x00fb36},
+ {0x00fb38, 0x00fb3c},
+ {0x00fb3e, 0x00fb3e},
+ {0x00fb40, 0x00fb41},
+ {0x00fb43, 0x00fb44},
+ {0x00fb46, 0x00fbb1},
+ {0x00fbd3, 0x00fd3d},
+ {0x00fd50, 0x00fd8f},
+ {0x00fd92, 0x00fdc7},
+ {0x00fdf0, 0x00fdfb},
+ {0x00fe70, 0x00fe74},
+ {0x00fe76, 0x00fefc},
+ {0x00ff21, 0x00ff3a},
+ {0x00ff41, 0x00ff5a},
+ {0x00ff66, 0x00ff6f},
+ {0x00ff70, 0x00ff70},
+ {0x00ff71, 0x00ff9d},
+ {0x00ff9e, 0x00ff9f},
+ {0x00ffa0, 0x00ffbe},
+ {0x00ffc2, 0x00ffc7},
+ {0x00ffca, 0x00ffcf},
+ {0x00ffd2, 0x00ffd7},
+ {0x00ffda, 0x00ffdc},
+ {0x010000, 0x01000b},
+ {0x01000d, 0x010026},
+ {0x010028, 0x01003a},
+ {0x01003c, 0x01003d},
+ {0x01003f, 0x01004d},
+ {0x010050, 0x01005d},
+ {0x010080, 0x0100fa},
+ {0x010140, 0x010174},
+ {0x010280, 0x01029c},
+ {0x0102a0, 0x0102d0},
+ {0x010300, 0x01031f},
+ {0x01032d, 0x010340},
+ {0x010341, 0x010341},
+ {0x010342, 0x010349},
+ {0x01034a, 0x01034a},
+ {0x010350, 0x010375},
+ {0x010376, 0x01037a},
+ {0x010380, 0x01039d},
+ {0x0103a0, 0x0103c3},
+ {0x0103c8, 0x0103cf},
+ {0x0103d1, 0x0103d5},
+ {0x010400, 0x01044f},
+ {0x010450, 0x01049d},
+ {0x0104b0, 0x0104d3},
+ {0x0104d8, 0x0104fb},
+ {0x010500, 0x010527},
+ {0x010530, 0x010563},
+ {0x010570, 0x01057a},
+ {0x01057c, 0x01058a},
+ {0x01058c, 0x010592},
+ {0x010594, 0x010595},
+ {0x010597, 0x0105a1},
+ {0x0105a3, 0x0105b1},
+ {0x0105b3, 0x0105b9},
+ {0x0105bb, 0x0105bc},
+ {0x010600, 0x010736},
+ {0x010740, 0x010755},
+ {0x010760, 0x010767},
+ {0x010780, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010800, 0x010805},
+ {0x010808, 0x010808},
+ {0x01080a, 0x010835},
+ {0x010837, 0x010838},
+ {0x01083c, 0x01083c},
+ {0x01083f, 0x010855},
+ {0x010860, 0x010876},
+ {0x010880, 0x01089e},
+ {0x0108e0, 0x0108f2},
+ {0x0108f4, 0x0108f5},
+ {0x010900, 0x010915},
+ {0x010920, 0x010939},
+ {0x010980, 0x0109b7},
+ {0x0109be, 0x0109bf},
+ {0x010a00, 0x010a00},
+ {0x010a01, 0x010a03},
+ {0x010a05, 0x010a06},
+ {0x010a0c, 0x010a0f},
+ {0x010a10, 0x010a13},
+ {0x010a15, 0x010a17},
+ {0x010a19, 0x010a35},
+ {0x010a60, 0x010a7c},
+ {0x010a80, 0x010a9c},
+ {0x010ac0, 0x010ac7},
+ {0x010ac9, 0x010ae4},
+ {0x010b00, 0x010b35},
+ {0x010b40, 0x010b55},
+ {0x010b60, 0x010b72},
+ {0x010b80, 0x010b91},
+ {0x010c00, 0x010c48},
+ {0x010c80, 0x010cb2},
+ {0x010cc0, 0x010cf2},
+ {0x010d00, 0x010d23},
+ {0x010d24, 0x010d27},
+ {0x010e80, 0x010ea9},
+ {0x010eab, 0x010eac},
+ {0x010eb0, 0x010eb1},
+ {0x010f00, 0x010f1c},
+ {0x010f27, 0x010f27},
+ {0x010f30, 0x010f45},
+ {0x010f70, 0x010f81},
+ {0x010fb0, 0x010fc4},
+ {0x010fe0, 0x010ff6},
+ {0x011000, 0x011000},
+ {0x011001, 0x011001},
+ {0x011002, 0x011002},
+ {0x011003, 0x011037},
+ {0x011038, 0x011045},
+ {0x011071, 0x011072},
+ {0x011073, 0x011074},
+ {0x011075, 0x011075},
+ {0x011080, 0x011081},
+ {0x011082, 0x011082},
+ {0x011083, 0x0110af},
+ {0x0110b0, 0x0110b2},
+ {0x0110b3, 0x0110b6},
+ {0x0110b7, 0x0110b8},
+ {0x0110c2, 0x0110c2},
+ {0x0110d0, 0x0110e8},
+ {0x011100, 0x011102},
+ {0x011103, 0x011126},
+ {0x011127, 0x01112b},
+ {0x01112c, 0x01112c},
+ {0x01112d, 0x011132},
+ {0x011144, 0x011144},
+ {0x011145, 0x011146},
+ {0x011147, 0x011147},
+ {0x011150, 0x011172},
+ {0x011176, 0x011176},
+ {0x011180, 0x011181},
+ {0x011182, 0x011182},
+ {0x011183, 0x0111b2},
+ {0x0111b3, 0x0111b5},
+ {0x0111b6, 0x0111be},
+ {0x0111bf, 0x0111bf},
+ {0x0111c1, 0x0111c4},
+ {0x0111ce, 0x0111ce},
+ {0x0111cf, 0x0111cf},
+ {0x0111da, 0x0111da},
+ {0x0111dc, 0x0111dc},
+ {0x011200, 0x011211},
+ {0x011213, 0x01122b},
+ {0x01122c, 0x01122e},
+ {0x01122f, 0x011231},
+ {0x011232, 0x011233},
+ {0x011234, 0x011234},
+ {0x011237, 0x011237},
+ {0x01123e, 0x01123e},
+ {0x01123f, 0x011240},
+ {0x011241, 0x011241},
+ {0x011280, 0x011286},
+ {0x011288, 0x011288},
+ {0x01128a, 0x01128d},
+ {0x01128f, 0x01129d},
+ {0x01129f, 0x0112a8},
+ {0x0112b0, 0x0112de},
+ {0x0112df, 0x0112df},
+ {0x0112e0, 0x0112e2},
+ {0x0112e3, 0x0112e8},
+ {0x011300, 0x011301},
+ {0x011302, 0x011303},
+ {0x011305, 0x01130c},
+ {0x01130f, 0x011310},
+ {0x011313, 0x011328},
+ {0x01132a, 0x011330},
+ {0x011332, 0x011333},
+ {0x011335, 0x011339},
+ {0x01133d, 0x01133d},
+ {0x01133e, 0x01133f},
+ {0x011340, 0x011340},
+ {0x011341, 0x011344},
+ {0x011347, 0x011348},
+ {0x01134b, 0x01134c},
+ {0x011350, 0x011350},
+ {0x011357, 0x011357},
+ {0x01135d, 0x011361},
+ {0x011362, 0x011363},
+ {0x011400, 0x011434},
+ {0x011435, 0x011437},
+ {0x011438, 0x01143f},
+ {0x011440, 0x011441},
+ {0x011443, 0x011444},
+ {0x011445, 0x011445},
+ {0x011447, 0x01144a},
+ {0x01145f, 0x011461},
+ {0x011480, 0x0114af},
+ {0x0114b0, 0x0114b2},
+ {0x0114b3, 0x0114b8},
+ {0x0114b9, 0x0114b9},
+ {0x0114ba, 0x0114ba},
+ {0x0114bb, 0x0114be},
+ {0x0114bf, 0x0114c0},
+ {0x0114c1, 0x0114c1},
+ {0x0114c4, 0x0114c5},
+ {0x0114c7, 0x0114c7},
+ {0x011580, 0x0115ae},
+ {0x0115af, 0x0115b1},
+ {0x0115b2, 0x0115b5},
+ {0x0115b8, 0x0115bb},
+ {0x0115bc, 0x0115bd},
+ {0x0115be, 0x0115be},
+ {0x0115d8, 0x0115db},
+ {0x0115dc, 0x0115dd},
+ {0x011600, 0x01162f},
+ {0x011630, 0x011632},
+ {0x011633, 0x01163a},
+ {0x01163b, 0x01163c},
+ {0x01163d, 0x01163d},
+ {0x01163e, 0x01163e},
+ {0x011640, 0x011640},
+ {0x011644, 0x011644},
+ {0x011680, 0x0116aa},
+ {0x0116ab, 0x0116ab},
+ {0x0116ac, 0x0116ac},
+ {0x0116ad, 0x0116ad},
+ {0x0116ae, 0x0116af},
+ {0x0116b0, 0x0116b5},
+ {0x0116b8, 0x0116b8},
+ {0x011700, 0x01171a},
+ {0x01171d, 0x01171f},
+ {0x011720, 0x011721},
+ {0x011722, 0x011725},
+ {0x011726, 0x011726},
+ {0x011727, 0x01172a},
+ {0x011740, 0x011746},
+ {0x011800, 0x01182b},
+ {0x01182c, 0x01182e},
+ {0x01182f, 0x011837},
+ {0x011838, 0x011838},
+ {0x0118a0, 0x0118df},
+ {0x0118ff, 0x011906},
+ {0x011909, 0x011909},
+ {0x01190c, 0x011913},
+ {0x011915, 0x011916},
+ {0x011918, 0x01192f},
+ {0x011930, 0x011935},
+ {0x011937, 0x011938},
+ {0x01193b, 0x01193c},
+ {0x01193f, 0x01193f},
+ {0x011940, 0x011940},
+ {0x011941, 0x011941},
+ {0x011942, 0x011942},
+ {0x0119a0, 0x0119a7},
+ {0x0119aa, 0x0119d0},
+ {0x0119d1, 0x0119d3},
+ {0x0119d4, 0x0119d7},
+ {0x0119da, 0x0119db},
+ {0x0119dc, 0x0119df},
+ {0x0119e1, 0x0119e1},
+ {0x0119e3, 0x0119e3},
+ {0x0119e4, 0x0119e4},
+ {0x011a00, 0x011a00},
+ {0x011a01, 0x011a0a},
+ {0x011a0b, 0x011a32},
+ {0x011a35, 0x011a38},
+ {0x011a39, 0x011a39},
+ {0x011a3a, 0x011a3a},
+ {0x011a3b, 0x011a3e},
+ {0x011a50, 0x011a50},
+ {0x011a51, 0x011a56},
+ {0x011a57, 0x011a58},
+ {0x011a59, 0x011a5b},
+ {0x011a5c, 0x011a89},
+ {0x011a8a, 0x011a96},
+ {0x011a97, 0x011a97},
+ {0x011a9d, 0x011a9d},
+ {0x011ab0, 0x011af8},
+ {0x011c00, 0x011c08},
+ {0x011c0a, 0x011c2e},
+ {0x011c2f, 0x011c2f},
+ {0x011c30, 0x011c36},
+ {0x011c38, 0x011c3d},
+ {0x011c3e, 0x011c3e},
+ {0x011c40, 0x011c40},
+ {0x011c72, 0x011c8f},
+ {0x011c92, 0x011ca7},
+ {0x011ca9, 0x011ca9},
+ {0x011caa, 0x011cb0},
+ {0x011cb1, 0x011cb1},
+ {0x011cb2, 0x011cb3},
+ {0x011cb4, 0x011cb4},
+ {0x011cb5, 0x011cb6},
+ {0x011d00, 0x011d06},
+ {0x011d08, 0x011d09},
+ {0x011d0b, 0x011d30},
+ {0x011d31, 0x011d36},
+ {0x011d3a, 0x011d3a},
+ {0x011d3c, 0x011d3d},
+ {0x011d3f, 0x011d41},
+ {0x011d43, 0x011d43},
+ {0x011d46, 0x011d46},
+ {0x011d47, 0x011d47},
+ {0x011d60, 0x011d65},
+ {0x011d67, 0x011d68},
+ {0x011d6a, 0x011d89},
+ {0x011d8a, 0x011d8e},
+ {0x011d90, 0x011d91},
+ {0x011d93, 0x011d94},
+ {0x011d95, 0x011d95},
+ {0x011d96, 0x011d96},
+ {0x011d98, 0x011d98},
+ {0x011ee0, 0x011ef2},
+ {0x011ef3, 0x011ef4},
+ {0x011ef5, 0x011ef6},
+ {0x011f00, 0x011f01},
+ {0x011f02, 0x011f02},
+ {0x011f03, 0x011f03},
+ {0x011f04, 0x011f10},
+ {0x011f12, 0x011f33},
+ {0x011f34, 0x011f35},
+ {0x011f36, 0x011f3a},
+ {0x011f3e, 0x011f3f},
+ {0x011f40, 0x011f40},
+ {0x011fb0, 0x011fb0},
+ {0x012000, 0x012399},
+ {0x012400, 0x01246e},
+ {0x012480, 0x012543},
+ {0x012f90, 0x012ff0},
+ {0x013000, 0x01342f},
+ {0x013441, 0x013446},
+ {0x014400, 0x014646},
+ {0x016800, 0x016a38},
+ {0x016a40, 0x016a5e},
+ {0x016a70, 0x016abe},
+ {0x016ad0, 0x016aed},
+ {0x016b00, 0x016b2f},
+ {0x016b40, 0x016b43},
+ {0x016b63, 0x016b77},
+ {0x016b7d, 0x016b8f},
+ {0x016e40, 0x016e7f},
+ {0x016f00, 0x016f4a},
+ {0x016f4f, 0x016f4f},
+ {0x016f50, 0x016f50},
+ {0x016f51, 0x016f87},
+ {0x016f8f, 0x016f92},
+ {0x016f93, 0x016f9f},
+ {0x016fe0, 0x016fe1},
+ {0x016fe3, 0x016fe3},
+ {0x016ff0, 0x016ff1},
+ {0x017000, 0x0187f7},
+ {0x018800, 0x018cd5},
+ {0x018d00, 0x018d08},
+ {0x01aff0, 0x01aff3},
+ {0x01aff5, 0x01affb},
+ {0x01affd, 0x01affe},
+ {0x01b000, 0x01b122},
+ {0x01b132, 0x01b132},
+ {0x01b150, 0x01b152},
+ {0x01b155, 0x01b155},
+ {0x01b164, 0x01b167},
+ {0x01b170, 0x01b2fb},
+ {0x01bc00, 0x01bc6a},
+ {0x01bc70, 0x01bc7c},
+ {0x01bc80, 0x01bc88},
+ {0x01bc90, 0x01bc99},
+ {0x01bc9e, 0x01bc9e},
+ {0x01d400, 0x01d454},
+ {0x01d456, 0x01d49c},
+ {0x01d49e, 0x01d49f},
+ {0x01d4a2, 0x01d4a2},
+ {0x01d4a5, 0x01d4a6},
+ {0x01d4a9, 0x01d4ac},
+ {0x01d4ae, 0x01d4b9},
+ {0x01d4bb, 0x01d4bb},
+ {0x01d4bd, 0x01d4c3},
+ {0x01d4c5, 0x01d505},
+ {0x01d507, 0x01d50a},
+ {0x01d50d, 0x01d514},
+ {0x01d516, 0x01d51c},
+ {0x01d51e, 0x01d539},
+ {0x01d53b, 0x01d53e},
+ {0x01d540, 0x01d544},
+ {0x01d546, 0x01d546},
+ {0x01d54a, 0x01d550},
+ {0x01d552, 0x01d6a5},
+ {0x01d6a8, 0x01d6c0},
+ {0x01d6c2, 0x01d6da},
+ {0x01d6dc, 0x01d6fa},
+ {0x01d6fc, 0x01d714},
+ {0x01d716, 0x01d734},
+ {0x01d736, 0x01d74e},
+ {0x01d750, 0x01d76e},
+ {0x01d770, 0x01d788},
+ {0x01d78a, 0x01d7a8},
+ {0x01d7aa, 0x01d7c2},
+ {0x01d7c4, 0x01d7cb},
+ {0x01df00, 0x01df09},
+ {0x01df0a, 0x01df0a},
+ {0x01df0b, 0x01df1e},
+ {0x01df25, 0x01df2a},
+ {0x01e000, 0x01e006},
+ {0x01e008, 0x01e018},
+ {0x01e01b, 0x01e021},
+ {0x01e023, 0x01e024},
+ {0x01e026, 0x01e02a},
+ {0x01e030, 0x01e06d},
+ {0x01e08f, 0x01e08f},
+ {0x01e100, 0x01e12c},
+ {0x01e137, 0x01e13d},
+ {0x01e14e, 0x01e14e},
+ {0x01e290, 0x01e2ad},
+ {0x01e2c0, 0x01e2eb},
+ {0x01e4d0, 0x01e4ea},
+ {0x01e4eb, 0x01e4eb},
+ {0x01e7e0, 0x01e7e6},
+ {0x01e7e8, 0x01e7eb},
+ {0x01e7ed, 0x01e7ee},
+ {0x01e7f0, 0x01e7fe},
+ {0x01e800, 0x01e8c4},
+ {0x01e900, 0x01e943},
+ {0x01e947, 0x01e947},
+ {0x01e94b, 0x01e94b},
+ {0x01ee00, 0x01ee03},
+ {0x01ee05, 0x01ee1f},
+ {0x01ee21, 0x01ee22},
+ {0x01ee24, 0x01ee24},
+ {0x01ee27, 0x01ee27},
+ {0x01ee29, 0x01ee32},
+ {0x01ee34, 0x01ee37},
+ {0x01ee39, 0x01ee39},
+ {0x01ee3b, 0x01ee3b},
+ {0x01ee42, 0x01ee42},
+ {0x01ee47, 0x01ee47},
+ {0x01ee49, 0x01ee49},
+ {0x01ee4b, 0x01ee4b},
+ {0x01ee4d, 0x01ee4f},
+ {0x01ee51, 0x01ee52},
+ {0x01ee54, 0x01ee54},
+ {0x01ee57, 0x01ee57},
+ {0x01ee59, 0x01ee59},
+ {0x01ee5b, 0x01ee5b},
+ {0x01ee5d, 0x01ee5d},
+ {0x01ee5f, 0x01ee5f},
+ {0x01ee61, 0x01ee62},
+ {0x01ee64, 0x01ee64},
+ {0x01ee67, 0x01ee6a},
+ {0x01ee6c, 0x01ee72},
+ {0x01ee74, 0x01ee77},
+ {0x01ee79, 0x01ee7c},
+ {0x01ee7e, 0x01ee7e},
+ {0x01ee80, 0x01ee89},
+ {0x01ee8b, 0x01ee9b},
+ {0x01eea1, 0x01eea3},
+ {0x01eea5, 0x01eea9},
+ {0x01eeab, 0x01eebb},
+ {0x01f130, 0x01f149},
+ {0x01f150, 0x01f169},
+ {0x01f170, 0x01f189},
+ {0x020000, 0x02a6df},
+ {0x02a700, 0x02b739},
+ {0x02b740, 0x02b81d},
+ {0x02b820, 0x02cea1},
+ {0x02ceb0, 0x02ebe0},
+ {0x02ebf0, 0x02ee5d},
+ {0x02f800, 0x02fa1d},
+ {0x030000, 0x03134a},
+ {0x031350, 0x0323af},
+};
+
+/* table of Unicode codepoint ranges of Lowercase characters */
+static const pg_unicode_range unicode_lowercase[686] =
+{
+ {0x000061, 0x00007a},
+ {0x0000aa, 0x0000aa},
+ {0x0000b5, 0x0000b5},
+ {0x0000ba, 0x0000ba},
+ {0x0000df, 0x0000f6},
+ {0x0000f8, 0x0000ff},
+ {0x000101, 0x000101},
+ {0x000103, 0x000103},
+ {0x000105, 0x000105},
+ {0x000107, 0x000107},
+ {0x000109, 0x000109},
+ {0x00010b, 0x00010b},
+ {0x00010d, 0x00010d},
+ {0x00010f, 0x00010f},
+ {0x000111, 0x000111},
+ {0x000113, 0x000113},
+ {0x000115, 0x000115},
+ {0x000117, 0x000117},
+ {0x000119, 0x000119},
+ {0x00011b, 0x00011b},
+ {0x00011d, 0x00011d},
+ {0x00011f, 0x00011f},
+ {0x000121, 0x000121},
+ {0x000123, 0x000123},
+ {0x000125, 0x000125},
+ {0x000127, 0x000127},
+ {0x000129, 0x000129},
+ {0x00012b, 0x00012b},
+ {0x00012d, 0x00012d},
+ {0x00012f, 0x00012f},
+ {0x000131, 0x000131},
+ {0x000133, 0x000133},
+ {0x000135, 0x000135},
+ {0x000137, 0x000138},
+ {0x00013a, 0x00013a},
+ {0x00013c, 0x00013c},
+ {0x00013e, 0x00013e},
+ {0x000140, 0x000140},
+ {0x000142, 0x000142},
+ {0x000144, 0x000144},
+ {0x000146, 0x000146},
+ {0x000148, 0x000149},
+ {0x00014b, 0x00014b},
+ {0x00014d, 0x00014d},
+ {0x00014f, 0x00014f},
+ {0x000151, 0x000151},
+ {0x000153, 0x000153},
+ {0x000155, 0x000155},
+ {0x000157, 0x000157},
+ {0x000159, 0x000159},
+ {0x00015b, 0x00015b},
+ {0x00015d, 0x00015d},
+ {0x00015f, 0x00015f},
+ {0x000161, 0x000161},
+ {0x000163, 0x000163},
+ {0x000165, 0x000165},
+ {0x000167, 0x000167},
+ {0x000169, 0x000169},
+ {0x00016b, 0x00016b},
+ {0x00016d, 0x00016d},
+ {0x00016f, 0x00016f},
+ {0x000171, 0x000171},
+ {0x000173, 0x000173},
+ {0x000175, 0x000175},
+ {0x000177, 0x000177},
+ {0x00017a, 0x00017a},
+ {0x00017c, 0x00017c},
+ {0x00017e, 0x000180},
+ {0x000183, 0x000183},
+ {0x000185, 0x000185},
+ {0x000188, 0x000188},
+ {0x00018c, 0x00018d},
+ {0x000192, 0x000192},
+ {0x000195, 0x000195},
+ {0x000199, 0x00019b},
+ {0x00019e, 0x00019e},
+ {0x0001a1, 0x0001a1},
+ {0x0001a3, 0x0001a3},
+ {0x0001a5, 0x0001a5},
+ {0x0001a8, 0x0001a8},
+ {0x0001aa, 0x0001ab},
+ {0x0001ad, 0x0001ad},
+ {0x0001b0, 0x0001b0},
+ {0x0001b4, 0x0001b4},
+ {0x0001b6, 0x0001b6},
+ {0x0001b9, 0x0001ba},
+ {0x0001bd, 0x0001bf},
+ {0x0001c6, 0x0001c6},
+ {0x0001c9, 0x0001c9},
+ {0x0001cc, 0x0001cc},
+ {0x0001ce, 0x0001ce},
+ {0x0001d0, 0x0001d0},
+ {0x0001d2, 0x0001d2},
+ {0x0001d4, 0x0001d4},
+ {0x0001d6, 0x0001d6},
+ {0x0001d8, 0x0001d8},
+ {0x0001da, 0x0001da},
+ {0x0001dc, 0x0001dd},
+ {0x0001df, 0x0001df},
+ {0x0001e1, 0x0001e1},
+ {0x0001e3, 0x0001e3},
+ {0x0001e5, 0x0001e5},
+ {0x0001e7, 0x0001e7},
+ {0x0001e9, 0x0001e9},
+ {0x0001eb, 0x0001eb},
+ {0x0001ed, 0x0001ed},
+ {0x0001ef, 0x0001f0},
+ {0x0001f3, 0x0001f3},
+ {0x0001f5, 0x0001f5},
+ {0x0001f9, 0x0001f9},
+ {0x0001fb, 0x0001fb},
+ {0x0001fd, 0x0001fd},
+ {0x0001ff, 0x0001ff},
+ {0x000201, 0x000201},
+ {0x000203, 0x000203},
+ {0x000205, 0x000205},
+ {0x000207, 0x000207},
+ {0x000209, 0x000209},
+ {0x00020b, 0x00020b},
+ {0x00020d, 0x00020d},
+ {0x00020f, 0x00020f},
+ {0x000211, 0x000211},
+ {0x000213, 0x000213},
+ {0x000215, 0x000215},
+ {0x000217, 0x000217},
+ {0x000219, 0x000219},
+ {0x00021b, 0x00021b},
+ {0x00021d, 0x00021d},
+ {0x00021f, 0x00021f},
+ {0x000221, 0x000221},
+ {0x000223, 0x000223},
+ {0x000225, 0x000225},
+ {0x000227, 0x000227},
+ {0x000229, 0x000229},
+ {0x00022b, 0x00022b},
+ {0x00022d, 0x00022d},
+ {0x00022f, 0x00022f},
+ {0x000231, 0x000231},
+ {0x000233, 0x000239},
+ {0x00023c, 0x00023c},
+ {0x00023f, 0x000240},
+ {0x000242, 0x000242},
+ {0x000247, 0x000247},
+ {0x000249, 0x000249},
+ {0x00024b, 0x00024b},
+ {0x00024d, 0x00024d},
+ {0x00024f, 0x000293},
+ {0x000295, 0x0002af},
+ {0x0002b0, 0x0002b8},
+ {0x0002c0, 0x0002c1},
+ {0x0002e0, 0x0002e4},
+ {0x000345, 0x000345},
+ {0x000371, 0x000371},
+ {0x000373, 0x000373},
+ {0x000377, 0x000377},
+ {0x00037a, 0x00037a},
+ {0x00037b, 0x00037d},
+ {0x000390, 0x000390},
+ {0x0003ac, 0x0003ce},
+ {0x0003d0, 0x0003d1},
+ {0x0003d5, 0x0003d7},
+ {0x0003d9, 0x0003d9},
+ {0x0003db, 0x0003db},
+ {0x0003dd, 0x0003dd},
+ {0x0003df, 0x0003df},
+ {0x0003e1, 0x0003e1},
+ {0x0003e3, 0x0003e3},
+ {0x0003e5, 0x0003e5},
+ {0x0003e7, 0x0003e7},
+ {0x0003e9, 0x0003e9},
+ {0x0003eb, 0x0003eb},
+ {0x0003ed, 0x0003ed},
+ {0x0003ef, 0x0003f3},
+ {0x0003f5, 0x0003f5},
+ {0x0003f8, 0x0003f8},
+ {0x0003fb, 0x0003fc},
+ {0x000430, 0x00045f},
+ {0x000461, 0x000461},
+ {0x000463, 0x000463},
+ {0x000465, 0x000465},
+ {0x000467, 0x000467},
+ {0x000469, 0x000469},
+ {0x00046b, 0x00046b},
+ {0x00046d, 0x00046d},
+ {0x00046f, 0x00046f},
+ {0x000471, 0x000471},
+ {0x000473, 0x000473},
+ {0x000475, 0x000475},
+ {0x000477, 0x000477},
+ {0x000479, 0x000479},
+ {0x00047b, 0x00047b},
+ {0x00047d, 0x00047d},
+ {0x00047f, 0x00047f},
+ {0x000481, 0x000481},
+ {0x00048b, 0x00048b},
+ {0x00048d, 0x00048d},
+ {0x00048f, 0x00048f},
+ {0x000491, 0x000491},
+ {0x000493, 0x000493},
+ {0x000495, 0x000495},
+ {0x000497, 0x000497},
+ {0x000499, 0x000499},
+ {0x00049b, 0x00049b},
+ {0x00049d, 0x00049d},
+ {0x00049f, 0x00049f},
+ {0x0004a1, 0x0004a1},
+ {0x0004a3, 0x0004a3},
+ {0x0004a5, 0x0004a5},
+ {0x0004a7, 0x0004a7},
+ {0x0004a9, 0x0004a9},
+ {0x0004ab, 0x0004ab},
+ {0x0004ad, 0x0004ad},
+ {0x0004af, 0x0004af},
+ {0x0004b1, 0x0004b1},
+ {0x0004b3, 0x0004b3},
+ {0x0004b5, 0x0004b5},
+ {0x0004b7, 0x0004b7},
+ {0x0004b9, 0x0004b9},
+ {0x0004bb, 0x0004bb},
+ {0x0004bd, 0x0004bd},
+ {0x0004bf, 0x0004bf},
+ {0x0004c2, 0x0004c2},
+ {0x0004c4, 0x0004c4},
+ {0x0004c6, 0x0004c6},
+ {0x0004c8, 0x0004c8},
+ {0x0004ca, 0x0004ca},
+ {0x0004cc, 0x0004cc},
+ {0x0004ce, 0x0004cf},
+ {0x0004d1, 0x0004d1},
+ {0x0004d3, 0x0004d3},
+ {0x0004d5, 0x0004d5},
+ {0x0004d7, 0x0004d7},
+ {0x0004d9, 0x0004d9},
+ {0x0004db, 0x0004db},
+ {0x0004dd, 0x0004dd},
+ {0x0004df, 0x0004df},
+ {0x0004e1, 0x0004e1},
+ {0x0004e3, 0x0004e3},
+ {0x0004e5, 0x0004e5},
+ {0x0004e7, 0x0004e7},
+ {0x0004e9, 0x0004e9},
+ {0x0004eb, 0x0004eb},
+ {0x0004ed, 0x0004ed},
+ {0x0004ef, 0x0004ef},
+ {0x0004f1, 0x0004f1},
+ {0x0004f3, 0x0004f3},
+ {0x0004f5, 0x0004f5},
+ {0x0004f7, 0x0004f7},
+ {0x0004f9, 0x0004f9},
+ {0x0004fb, 0x0004fb},
+ {0x0004fd, 0x0004fd},
+ {0x0004ff, 0x0004ff},
+ {0x000501, 0x000501},
+ {0x000503, 0x000503},
+ {0x000505, 0x000505},
+ {0x000507, 0x000507},
+ {0x000509, 0x000509},
+ {0x00050b, 0x00050b},
+ {0x00050d, 0x00050d},
+ {0x00050f, 0x00050f},
+ {0x000511, 0x000511},
+ {0x000513, 0x000513},
+ {0x000515, 0x000515},
+ {0x000517, 0x000517},
+ {0x000519, 0x000519},
+ {0x00051b, 0x00051b},
+ {0x00051d, 0x00051d},
+ {0x00051f, 0x00051f},
+ {0x000521, 0x000521},
+ {0x000523, 0x000523},
+ {0x000525, 0x000525},
+ {0x000527, 0x000527},
+ {0x000529, 0x000529},
+ {0x00052b, 0x00052b},
+ {0x00052d, 0x00052d},
+ {0x00052f, 0x00052f},
+ {0x000560, 0x000588},
+ {0x0010d0, 0x0010fa},
+ {0x0010fc, 0x0010fc},
+ {0x0010fd, 0x0010ff},
+ {0x0013f8, 0x0013fd},
+ {0x001c80, 0x001c88},
+ {0x001d00, 0x001d2b},
+ {0x001d2c, 0x001d6a},
+ {0x001d6b, 0x001d77},
+ {0x001d78, 0x001d78},
+ {0x001d79, 0x001d9a},
+ {0x001d9b, 0x001dbf},
+ {0x001e01, 0x001e01},
+ {0x001e03, 0x001e03},
+ {0x001e05, 0x001e05},
+ {0x001e07, 0x001e07},
+ {0x001e09, 0x001e09},
+ {0x001e0b, 0x001e0b},
+ {0x001e0d, 0x001e0d},
+ {0x001e0f, 0x001e0f},
+ {0x001e11, 0x001e11},
+ {0x001e13, 0x001e13},
+ {0x001e15, 0x001e15},
+ {0x001e17, 0x001e17},
+ {0x001e19, 0x001e19},
+ {0x001e1b, 0x001e1b},
+ {0x001e1d, 0x001e1d},
+ {0x001e1f, 0x001e1f},
+ {0x001e21, 0x001e21},
+ {0x001e23, 0x001e23},
+ {0x001e25, 0x001e25},
+ {0x001e27, 0x001e27},
+ {0x001e29, 0x001e29},
+ {0x001e2b, 0x001e2b},
+ {0x001e2d, 0x001e2d},
+ {0x001e2f, 0x001e2f},
+ {0x001e31, 0x001e31},
+ {0x001e33, 0x001e33},
+ {0x001e35, 0x001e35},
+ {0x001e37, 0x001e37},
+ {0x001e39, 0x001e39},
+ {0x001e3b, 0x001e3b},
+ {0x001e3d, 0x001e3d},
+ {0x001e3f, 0x001e3f},
+ {0x001e41, 0x001e41},
+ {0x001e43, 0x001e43},
+ {0x001e45, 0x001e45},
+ {0x001e47, 0x001e47},
+ {0x001e49, 0x001e49},
+ {0x001e4b, 0x001e4b},
+ {0x001e4d, 0x001e4d},
+ {0x001e4f, 0x001e4f},
+ {0x001e51, 0x001e51},
+ {0x001e53, 0x001e53},
+ {0x001e55, 0x001e55},
+ {0x001e57, 0x001e57},
+ {0x001e59, 0x001e59},
+ {0x001e5b, 0x001e5b},
+ {0x001e5d, 0x001e5d},
+ {0x001e5f, 0x001e5f},
+ {0x001e61, 0x001e61},
+ {0x001e63, 0x001e63},
+ {0x001e65, 0x001e65},
+ {0x001e67, 0x001e67},
+ {0x001e69, 0x001e69},
+ {0x001e6b, 0x001e6b},
+ {0x001e6d, 0x001e6d},
+ {0x001e6f, 0x001e6f},
+ {0x001e71, 0x001e71},
+ {0x001e73, 0x001e73},
+ {0x001e75, 0x001e75},
+ {0x001e77, 0x001e77},
+ {0x001e79, 0x001e79},
+ {0x001e7b, 0x001e7b},
+ {0x001e7d, 0x001e7d},
+ {0x001e7f, 0x001e7f},
+ {0x001e81, 0x001e81},
+ {0x001e83, 0x001e83},
+ {0x001e85, 0x001e85},
+ {0x001e87, 0x001e87},
+ {0x001e89, 0x001e89},
+ {0x001e8b, 0x001e8b},
+ {0x001e8d, 0x001e8d},
+ {0x001e8f, 0x001e8f},
+ {0x001e91, 0x001e91},
+ {0x001e93, 0x001e93},
+ {0x001e95, 0x001e9d},
+ {0x001e9f, 0x001e9f},
+ {0x001ea1, 0x001ea1},
+ {0x001ea3, 0x001ea3},
+ {0x001ea5, 0x001ea5},
+ {0x001ea7, 0x001ea7},
+ {0x001ea9, 0x001ea9},
+ {0x001eab, 0x001eab},
+ {0x001ead, 0x001ead},
+ {0x001eaf, 0x001eaf},
+ {0x001eb1, 0x001eb1},
+ {0x001eb3, 0x001eb3},
+ {0x001eb5, 0x001eb5},
+ {0x001eb7, 0x001eb7},
+ {0x001eb9, 0x001eb9},
+ {0x001ebb, 0x001ebb},
+ {0x001ebd, 0x001ebd},
+ {0x001ebf, 0x001ebf},
+ {0x001ec1, 0x001ec1},
+ {0x001ec3, 0x001ec3},
+ {0x001ec5, 0x001ec5},
+ {0x001ec7, 0x001ec7},
+ {0x001ec9, 0x001ec9},
+ {0x001ecb, 0x001ecb},
+ {0x001ecd, 0x001ecd},
+ {0x001ecf, 0x001ecf},
+ {0x001ed1, 0x001ed1},
+ {0x001ed3, 0x001ed3},
+ {0x001ed5, 0x001ed5},
+ {0x001ed7, 0x001ed7},
+ {0x001ed9, 0x001ed9},
+ {0x001edb, 0x001edb},
+ {0x001edd, 0x001edd},
+ {0x001edf, 0x001edf},
+ {0x001ee1, 0x001ee1},
+ {0x001ee3, 0x001ee3},
+ {0x001ee5, 0x001ee5},
+ {0x001ee7, 0x001ee7},
+ {0x001ee9, 0x001ee9},
+ {0x001eeb, 0x001eeb},
+ {0x001eed, 0x001eed},
+ {0x001eef, 0x001eef},
+ {0x001ef1, 0x001ef1},
+ {0x001ef3, 0x001ef3},
+ {0x001ef5, 0x001ef5},
+ {0x001ef7, 0x001ef7},
+ {0x001ef9, 0x001ef9},
+ {0x001efb, 0x001efb},
+ {0x001efd, 0x001efd},
+ {0x001eff, 0x001f07},
+ {0x001f10, 0x001f15},
+ {0x001f20, 0x001f27},
+ {0x001f30, 0x001f37},
+ {0x001f40, 0x001f45},
+ {0x001f50, 0x001f57},
+ {0x001f60, 0x001f67},
+ {0x001f70, 0x001f7d},
+ {0x001f80, 0x001f87},
+ {0x001f90, 0x001f97},
+ {0x001fa0, 0x001fa7},
+ {0x001fb0, 0x001fb4},
+ {0x001fb6, 0x001fb7},
+ {0x001fbe, 0x001fbe},
+ {0x001fc2, 0x001fc4},
+ {0x001fc6, 0x001fc7},
+ {0x001fd0, 0x001fd3},
+ {0x001fd6, 0x001fd7},
+ {0x001fe0, 0x001fe7},
+ {0x001ff2, 0x001ff4},
+ {0x001ff6, 0x001ff7},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x00210a, 0x00210a},
+ {0x00210e, 0x00210f},
+ {0x002113, 0x002113},
+ {0x00212f, 0x00212f},
+ {0x002134, 0x002134},
+ {0x002139, 0x002139},
+ {0x00213c, 0x00213d},
+ {0x002146, 0x002149},
+ {0x00214e, 0x00214e},
+ {0x002170, 0x00217f},
+ {0x002184, 0x002184},
+ {0x0024d0, 0x0024e9},
+ {0x002c30, 0x002c5f},
+ {0x002c61, 0x002c61},
+ {0x002c65, 0x002c66},
+ {0x002c68, 0x002c68},
+ {0x002c6a, 0x002c6a},
+ {0x002c6c, 0x002c6c},
+ {0x002c71, 0x002c71},
+ {0x002c73, 0x002c74},
+ {0x002c76, 0x002c7b},
+ {0x002c7c, 0x002c7d},
+ {0x002c81, 0x002c81},
+ {0x002c83, 0x002c83},
+ {0x002c85, 0x002c85},
+ {0x002c87, 0x002c87},
+ {0x002c89, 0x002c89},
+ {0x002c8b, 0x002c8b},
+ {0x002c8d, 0x002c8d},
+ {0x002c8f, 0x002c8f},
+ {0x002c91, 0x002c91},
+ {0x002c93, 0x002c93},
+ {0x002c95, 0x002c95},
+ {0x002c97, 0x002c97},
+ {0x002c99, 0x002c99},
+ {0x002c9b, 0x002c9b},
+ {0x002c9d, 0x002c9d},
+ {0x002c9f, 0x002c9f},
+ {0x002ca1, 0x002ca1},
+ {0x002ca3, 0x002ca3},
+ {0x002ca5, 0x002ca5},
+ {0x002ca7, 0x002ca7},
+ {0x002ca9, 0x002ca9},
+ {0x002cab, 0x002cab},
+ {0x002cad, 0x002cad},
+ {0x002caf, 0x002caf},
+ {0x002cb1, 0x002cb1},
+ {0x002cb3, 0x002cb3},
+ {0x002cb5, 0x002cb5},
+ {0x002cb7, 0x002cb7},
+ {0x002cb9, 0x002cb9},
+ {0x002cbb, 0x002cbb},
+ {0x002cbd, 0x002cbd},
+ {0x002cbf, 0x002cbf},
+ {0x002cc1, 0x002cc1},
+ {0x002cc3, 0x002cc3},
+ {0x002cc5, 0x002cc5},
+ {0x002cc7, 0x002cc7},
+ {0x002cc9, 0x002cc9},
+ {0x002ccb, 0x002ccb},
+ {0x002ccd, 0x002ccd},
+ {0x002ccf, 0x002ccf},
+ {0x002cd1, 0x002cd1},
+ {0x002cd3, 0x002cd3},
+ {0x002cd5, 0x002cd5},
+ {0x002cd7, 0x002cd7},
+ {0x002cd9, 0x002cd9},
+ {0x002cdb, 0x002cdb},
+ {0x002cdd, 0x002cdd},
+ {0x002cdf, 0x002cdf},
+ {0x002ce1, 0x002ce1},
+ {0x002ce3, 0x002ce4},
+ {0x002cec, 0x002cec},
+ {0x002cee, 0x002cee},
+ {0x002cf3, 0x002cf3},
+ {0x002d00, 0x002d25},
+ {0x002d27, 0x002d27},
+ {0x002d2d, 0x002d2d},
+ {0x00a641, 0x00a641},
+ {0x00a643, 0x00a643},
+ {0x00a645, 0x00a645},
+ {0x00a647, 0x00a647},
+ {0x00a649, 0x00a649},
+ {0x00a64b, 0x00a64b},
+ {0x00a64d, 0x00a64d},
+ {0x00a64f, 0x00a64f},
+ {0x00a651, 0x00a651},
+ {0x00a653, 0x00a653},
+ {0x00a655, 0x00a655},
+ {0x00a657, 0x00a657},
+ {0x00a659, 0x00a659},
+ {0x00a65b, 0x00a65b},
+ {0x00a65d, 0x00a65d},
+ {0x00a65f, 0x00a65f},
+ {0x00a661, 0x00a661},
+ {0x00a663, 0x00a663},
+ {0x00a665, 0x00a665},
+ {0x00a667, 0x00a667},
+ {0x00a669, 0x00a669},
+ {0x00a66b, 0x00a66b},
+ {0x00a66d, 0x00a66d},
+ {0x00a681, 0x00a681},
+ {0x00a683, 0x00a683},
+ {0x00a685, 0x00a685},
+ {0x00a687, 0x00a687},
+ {0x00a689, 0x00a689},
+ {0x00a68b, 0x00a68b},
+ {0x00a68d, 0x00a68d},
+ {0x00a68f, 0x00a68f},
+ {0x00a691, 0x00a691},
+ {0x00a693, 0x00a693},
+ {0x00a695, 0x00a695},
+ {0x00a697, 0x00a697},
+ {0x00a699, 0x00a699},
+ {0x00a69b, 0x00a69b},
+ {0x00a69c, 0x00a69d},
+ {0x00a723, 0x00a723},
+ {0x00a725, 0x00a725},
+ {0x00a727, 0x00a727},
+ {0x00a729, 0x00a729},
+ {0x00a72b, 0x00a72b},
+ {0x00a72d, 0x00a72d},
+ {0x00a72f, 0x00a731},
+ {0x00a733, 0x00a733},
+ {0x00a735, 0x00a735},
+ {0x00a737, 0x00a737},
+ {0x00a739, 0x00a739},
+ {0x00a73b, 0x00a73b},
+ {0x00a73d, 0x00a73d},
+ {0x00a73f, 0x00a73f},
+ {0x00a741, 0x00a741},
+ {0x00a743, 0x00a743},
+ {0x00a745, 0x00a745},
+ {0x00a747, 0x00a747},
+ {0x00a749, 0x00a749},
+ {0x00a74b, 0x00a74b},
+ {0x00a74d, 0x00a74d},
+ {0x00a74f, 0x00a74f},
+ {0x00a751, 0x00a751},
+ {0x00a753, 0x00a753},
+ {0x00a755, 0x00a755},
+ {0x00a757, 0x00a757},
+ {0x00a759, 0x00a759},
+ {0x00a75b, 0x00a75b},
+ {0x00a75d, 0x00a75d},
+ {0x00a75f, 0x00a75f},
+ {0x00a761, 0x00a761},
+ {0x00a763, 0x00a763},
+ {0x00a765, 0x00a765},
+ {0x00a767, 0x00a767},
+ {0x00a769, 0x00a769},
+ {0x00a76b, 0x00a76b},
+ {0x00a76d, 0x00a76d},
+ {0x00a76f, 0x00a76f},
+ {0x00a770, 0x00a770},
+ {0x00a771, 0x00a778},
+ {0x00a77a, 0x00a77a},
+ {0x00a77c, 0x00a77c},
+ {0x00a77f, 0x00a77f},
+ {0x00a781, 0x00a781},
+ {0x00a783, 0x00a783},
+ {0x00a785, 0x00a785},
+ {0x00a787, 0x00a787},
+ {0x00a78c, 0x00a78c},
+ {0x00a78e, 0x00a78e},
+ {0x00a791, 0x00a791},
+ {0x00a793, 0x00a795},
+ {0x00a797, 0x00a797},
+ {0x00a799, 0x00a799},
+ {0x00a79b, 0x00a79b},
+ {0x00a79d, 0x00a79d},
+ {0x00a79f, 0x00a79f},
+ {0x00a7a1, 0x00a7a1},
+ {0x00a7a3, 0x00a7a3},
+ {0x00a7a5, 0x00a7a5},
+ {0x00a7a7, 0x00a7a7},
+ {0x00a7a9, 0x00a7a9},
+ {0x00a7af, 0x00a7af},
+ {0x00a7b5, 0x00a7b5},
+ {0x00a7b7, 0x00a7b7},
+ {0x00a7b9, 0x00a7b9},
+ {0x00a7bb, 0x00a7bb},
+ {0x00a7bd, 0x00a7bd},
+ {0x00a7bf, 0x00a7bf},
+ {0x00a7c1, 0x00a7c1},
+ {0x00a7c3, 0x00a7c3},
+ {0x00a7c8, 0x00a7c8},
+ {0x00a7ca, 0x00a7ca},
+ {0x00a7d1, 0x00a7d1},
+ {0x00a7d3, 0x00a7d3},
+ {0x00a7d5, 0x00a7d5},
+ {0x00a7d7, 0x00a7d7},
+ {0x00a7d9, 0x00a7d9},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f6, 0x00a7f6},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a7fa, 0x00a7fa},
+ {0x00ab30, 0x00ab5a},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab60, 0x00ab68},
+ {0x00ab69, 0x00ab69},
+ {0x00ab70, 0x00abbf},
+ {0x00fb00, 0x00fb06},
+ {0x00fb13, 0x00fb17},
+ {0x00ff41, 0x00ff5a},
+ {0x010428, 0x01044f},
+ {0x0104d8, 0x0104fb},
+ {0x010597, 0x0105a1},
+ {0x0105a3, 0x0105b1},
+ {0x0105b3, 0x0105b9},
+ {0x0105bb, 0x0105bc},
+ {0x010780, 0x010780},
+ {0x010783, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010cc0, 0x010cf2},
+ {0x0118c0, 0x0118df},
+ {0x016e60, 0x016e7f},
+ {0x01d41a, 0x01d433},
+ {0x01d44e, 0x01d454},
+ {0x01d456, 0x01d467},
+ {0x01d482, 0x01d49b},
+ {0x01d4b6, 0x01d4b9},
+ {0x01d4bb, 0x01d4bb},
+ {0x01d4bd, 0x01d4c3},
+ {0x01d4c5, 0x01d4cf},
+ {0x01d4ea, 0x01d503},
+ {0x01d51e, 0x01d537},
+ {0x01d552, 0x01d56b},
+ {0x01d586, 0x01d59f},
+ {0x01d5ba, 0x01d5d3},
+ {0x01d5ee, 0x01d607},
+ {0x01d622, 0x01d63b},
+ {0x01d656, 0x01d66f},
+ {0x01d68a, 0x01d6a5},
+ {0x01d6c2, 0x01d6da},
+ {0x01d6dc, 0x01d6e1},
+ {0x01d6fc, 0x01d714},
+ {0x01d716, 0x01d71b},
+ {0x01d736, 0x01d74e},
+ {0x01d750, 0x01d755},
+ {0x01d770, 0x01d788},
+ {0x01d78a, 0x01d78f},
+ {0x01d7aa, 0x01d7c2},
+ {0x01d7c4, 0x01d7c9},
+ {0x01d7cb, 0x01d7cb},
+ {0x01df00, 0x01df09},
+ {0x01df0b, 0x01df1e},
+ {0x01df25, 0x01df2a},
+ {0x01e030, 0x01e06d},
+ {0x01e922, 0x01e943},
+};
+
+/* table of Unicode codepoint ranges of Uppercase characters */
+static const pg_unicode_range unicode_uppercase[651] =
+{
+ {0x000041, 0x00005a},
+ {0x0000c0, 0x0000d6},
+ {0x0000d8, 0x0000de},
+ {0x000100, 0x000100},
+ {0x000102, 0x000102},
+ {0x000104, 0x000104},
+ {0x000106, 0x000106},
+ {0x000108, 0x000108},
+ {0x00010a, 0x00010a},
+ {0x00010c, 0x00010c},
+ {0x00010e, 0x00010e},
+ {0x000110, 0x000110},
+ {0x000112, 0x000112},
+ {0x000114, 0x000114},
+ {0x000116, 0x000116},
+ {0x000118, 0x000118},
+ {0x00011a, 0x00011a},
+ {0x00011c, 0x00011c},
+ {0x00011e, 0x00011e},
+ {0x000120, 0x000120},
+ {0x000122, 0x000122},
+ {0x000124, 0x000124},
+ {0x000126, 0x000126},
+ {0x000128, 0x000128},
+ {0x00012a, 0x00012a},
+ {0x00012c, 0x00012c},
+ {0x00012e, 0x00012e},
+ {0x000130, 0x000130},
+ {0x000132, 0x000132},
+ {0x000134, 0x000134},
+ {0x000136, 0x000136},
+ {0x000139, 0x000139},
+ {0x00013b, 0x00013b},
+ {0x00013d, 0x00013d},
+ {0x00013f, 0x00013f},
+ {0x000141, 0x000141},
+ {0x000143, 0x000143},
+ {0x000145, 0x000145},
+ {0x000147, 0x000147},
+ {0x00014a, 0x00014a},
+ {0x00014c, 0x00014c},
+ {0x00014e, 0x00014e},
+ {0x000150, 0x000150},
+ {0x000152, 0x000152},
+ {0x000154, 0x000154},
+ {0x000156, 0x000156},
+ {0x000158, 0x000158},
+ {0x00015a, 0x00015a},
+ {0x00015c, 0x00015c},
+ {0x00015e, 0x00015e},
+ {0x000160, 0x000160},
+ {0x000162, 0x000162},
+ {0x000164, 0x000164},
+ {0x000166, 0x000166},
+ {0x000168, 0x000168},
+ {0x00016a, 0x00016a},
+ {0x00016c, 0x00016c},
+ {0x00016e, 0x00016e},
+ {0x000170, 0x000170},
+ {0x000172, 0x000172},
+ {0x000174, 0x000174},
+ {0x000176, 0x000176},
+ {0x000178, 0x000179},
+ {0x00017b, 0x00017b},
+ {0x00017d, 0x00017d},
+ {0x000181, 0x000182},
+ {0x000184, 0x000184},
+ {0x000186, 0x000187},
+ {0x000189, 0x00018b},
+ {0x00018e, 0x000191},
+ {0x000193, 0x000194},
+ {0x000196, 0x000198},
+ {0x00019c, 0x00019d},
+ {0x00019f, 0x0001a0},
+ {0x0001a2, 0x0001a2},
+ {0x0001a4, 0x0001a4},
+ {0x0001a6, 0x0001a7},
+ {0x0001a9, 0x0001a9},
+ {0x0001ac, 0x0001ac},
+ {0x0001ae, 0x0001af},
+ {0x0001b1, 0x0001b3},
+ {0x0001b5, 0x0001b5},
+ {0x0001b7, 0x0001b8},
+ {0x0001bc, 0x0001bc},
+ {0x0001c4, 0x0001c4},
+ {0x0001c7, 0x0001c7},
+ {0x0001ca, 0x0001ca},
+ {0x0001cd, 0x0001cd},
+ {0x0001cf, 0x0001cf},
+ {0x0001d1, 0x0001d1},
+ {0x0001d3, 0x0001d3},
+ {0x0001d5, 0x0001d5},
+ {0x0001d7, 0x0001d7},
+ {0x0001d9, 0x0001d9},
+ {0x0001db, 0x0001db},
+ {0x0001de, 0x0001de},
+ {0x0001e0, 0x0001e0},
+ {0x0001e2, 0x0001e2},
+ {0x0001e4, 0x0001e4},
+ {0x0001e6, 0x0001e6},
+ {0x0001e8, 0x0001e8},
+ {0x0001ea, 0x0001ea},
+ {0x0001ec, 0x0001ec},
+ {0x0001ee, 0x0001ee},
+ {0x0001f1, 0x0001f1},
+ {0x0001f4, 0x0001f4},
+ {0x0001f6, 0x0001f8},
+ {0x0001fa, 0x0001fa},
+ {0x0001fc, 0x0001fc},
+ {0x0001fe, 0x0001fe},
+ {0x000200, 0x000200},
+ {0x000202, 0x000202},
+ {0x000204, 0x000204},
+ {0x000206, 0x000206},
+ {0x000208, 0x000208},
+ {0x00020a, 0x00020a},
+ {0x00020c, 0x00020c},
+ {0x00020e, 0x00020e},
+ {0x000210, 0x000210},
+ {0x000212, 0x000212},
+ {0x000214, 0x000214},
+ {0x000216, 0x000216},
+ {0x000218, 0x000218},
+ {0x00021a, 0x00021a},
+ {0x00021c, 0x00021c},
+ {0x00021e, 0x00021e},
+ {0x000220, 0x000220},
+ {0x000222, 0x000222},
+ {0x000224, 0x000224},
+ {0x000226, 0x000226},
+ {0x000228, 0x000228},
+ {0x00022a, 0x00022a},
+ {0x00022c, 0x00022c},
+ {0x00022e, 0x00022e},
+ {0x000230, 0x000230},
+ {0x000232, 0x000232},
+ {0x00023a, 0x00023b},
+ {0x00023d, 0x00023e},
+ {0x000241, 0x000241},
+ {0x000243, 0x000246},
+ {0x000248, 0x000248},
+ {0x00024a, 0x00024a},
+ {0x00024c, 0x00024c},
+ {0x00024e, 0x00024e},
+ {0x000370, 0x000370},
+ {0x000372, 0x000372},
+ {0x000376, 0x000376},
+ {0x00037f, 0x00037f},
+ {0x000386, 0x000386},
+ {0x000388, 0x00038a},
+ {0x00038c, 0x00038c},
+ {0x00038e, 0x00038f},
+ {0x000391, 0x0003a1},
+ {0x0003a3, 0x0003ab},
+ {0x0003cf, 0x0003cf},
+ {0x0003d2, 0x0003d4},
+ {0x0003d8, 0x0003d8},
+ {0x0003da, 0x0003da},
+ {0x0003dc, 0x0003dc},
+ {0x0003de, 0x0003de},
+ {0x0003e0, 0x0003e0},
+ {0x0003e2, 0x0003e2},
+ {0x0003e4, 0x0003e4},
+ {0x0003e6, 0x0003e6},
+ {0x0003e8, 0x0003e8},
+ {0x0003ea, 0x0003ea},
+ {0x0003ec, 0x0003ec},
+ {0x0003ee, 0x0003ee},
+ {0x0003f4, 0x0003f4},
+ {0x0003f7, 0x0003f7},
+ {0x0003f9, 0x0003fa},
+ {0x0003fd, 0x00042f},
+ {0x000460, 0x000460},
+ {0x000462, 0x000462},
+ {0x000464, 0x000464},
+ {0x000466, 0x000466},
+ {0x000468, 0x000468},
+ {0x00046a, 0x00046a},
+ {0x00046c, 0x00046c},
+ {0x00046e, 0x00046e},
+ {0x000470, 0x000470},
+ {0x000472, 0x000472},
+ {0x000474, 0x000474},
+ {0x000476, 0x000476},
+ {0x000478, 0x000478},
+ {0x00047a, 0x00047a},
+ {0x00047c, 0x00047c},
+ {0x00047e, 0x00047e},
+ {0x000480, 0x000480},
+ {0x00048a, 0x00048a},
+ {0x00048c, 0x00048c},
+ {0x00048e, 0x00048e},
+ {0x000490, 0x000490},
+ {0x000492, 0x000492},
+ {0x000494, 0x000494},
+ {0x000496, 0x000496},
+ {0x000498, 0x000498},
+ {0x00049a, 0x00049a},
+ {0x00049c, 0x00049c},
+ {0x00049e, 0x00049e},
+ {0x0004a0, 0x0004a0},
+ {0x0004a2, 0x0004a2},
+ {0x0004a4, 0x0004a4},
+ {0x0004a6, 0x0004a6},
+ {0x0004a8, 0x0004a8},
+ {0x0004aa, 0x0004aa},
+ {0x0004ac, 0x0004ac},
+ {0x0004ae, 0x0004ae},
+ {0x0004b0, 0x0004b0},
+ {0x0004b2, 0x0004b2},
+ {0x0004b4, 0x0004b4},
+ {0x0004b6, 0x0004b6},
+ {0x0004b8, 0x0004b8},
+ {0x0004ba, 0x0004ba},
+ {0x0004bc, 0x0004bc},
+ {0x0004be, 0x0004be},
+ {0x0004c0, 0x0004c1},
+ {0x0004c3, 0x0004c3},
+ {0x0004c5, 0x0004c5},
+ {0x0004c7, 0x0004c7},
+ {0x0004c9, 0x0004c9},
+ {0x0004cb, 0x0004cb},
+ {0x0004cd, 0x0004cd},
+ {0x0004d0, 0x0004d0},
+ {0x0004d2, 0x0004d2},
+ {0x0004d4, 0x0004d4},
+ {0x0004d6, 0x0004d6},
+ {0x0004d8, 0x0004d8},
+ {0x0004da, 0x0004da},
+ {0x0004dc, 0x0004dc},
+ {0x0004de, 0x0004de},
+ {0x0004e0, 0x0004e0},
+ {0x0004e2, 0x0004e2},
+ {0x0004e4, 0x0004e4},
+ {0x0004e6, 0x0004e6},
+ {0x0004e8, 0x0004e8},
+ {0x0004ea, 0x0004ea},
+ {0x0004ec, 0x0004ec},
+ {0x0004ee, 0x0004ee},
+ {0x0004f0, 0x0004f0},
+ {0x0004f2, 0x0004f2},
+ {0x0004f4, 0x0004f4},
+ {0x0004f6, 0x0004f6},
+ {0x0004f8, 0x0004f8},
+ {0x0004fa, 0x0004fa},
+ {0x0004fc, 0x0004fc},
+ {0x0004fe, 0x0004fe},
+ {0x000500, 0x000500},
+ {0x000502, 0x000502},
+ {0x000504, 0x000504},
+ {0x000506, 0x000506},
+ {0x000508, 0x000508},
+ {0x00050a, 0x00050a},
+ {0x00050c, 0x00050c},
+ {0x00050e, 0x00050e},
+ {0x000510, 0x000510},
+ {0x000512, 0x000512},
+ {0x000514, 0x000514},
+ {0x000516, 0x000516},
+ {0x000518, 0x000518},
+ {0x00051a, 0x00051a},
+ {0x00051c, 0x00051c},
+ {0x00051e, 0x00051e},
+ {0x000520, 0x000520},
+ {0x000522, 0x000522},
+ {0x000524, 0x000524},
+ {0x000526, 0x000526},
+ {0x000528, 0x000528},
+ {0x00052a, 0x00052a},
+ {0x00052c, 0x00052c},
+ {0x00052e, 0x00052e},
+ {0x000531, 0x000556},
+ {0x0010a0, 0x0010c5},
+ {0x0010c7, 0x0010c7},
+ {0x0010cd, 0x0010cd},
+ {0x0013a0, 0x0013f5},
+ {0x001c90, 0x001cba},
+ {0x001cbd, 0x001cbf},
+ {0x001e00, 0x001e00},
+ {0x001e02, 0x001e02},
+ {0x001e04, 0x001e04},
+ {0x001e06, 0x001e06},
+ {0x001e08, 0x001e08},
+ {0x001e0a, 0x001e0a},
+ {0x001e0c, 0x001e0c},
+ {0x001e0e, 0x001e0e},
+ {0x001e10, 0x001e10},
+ {0x001e12, 0x001e12},
+ {0x001e14, 0x001e14},
+ {0x001e16, 0x001e16},
+ {0x001e18, 0x001e18},
+ {0x001e1a, 0x001e1a},
+ {0x001e1c, 0x001e1c},
+ {0x001e1e, 0x001e1e},
+ {0x001e20, 0x001e20},
+ {0x001e22, 0x001e22},
+ {0x001e24, 0x001e24},
+ {0x001e26, 0x001e26},
+ {0x001e28, 0x001e28},
+ {0x001e2a, 0x001e2a},
+ {0x001e2c, 0x001e2c},
+ {0x001e2e, 0x001e2e},
+ {0x001e30, 0x001e30},
+ {0x001e32, 0x001e32},
+ {0x001e34, 0x001e34},
+ {0x001e36, 0x001e36},
+ {0x001e38, 0x001e38},
+ {0x001e3a, 0x001e3a},
+ {0x001e3c, 0x001e3c},
+ {0x001e3e, 0x001e3e},
+ {0x001e40, 0x001e40},
+ {0x001e42, 0x001e42},
+ {0x001e44, 0x001e44},
+ {0x001e46, 0x001e46},
+ {0x001e48, 0x001e48},
+ {0x001e4a, 0x001e4a},
+ {0x001e4c, 0x001e4c},
+ {0x001e4e, 0x001e4e},
+ {0x001e50, 0x001e50},
+ {0x001e52, 0x001e52},
+ {0x001e54, 0x001e54},
+ {0x001e56, 0x001e56},
+ {0x001e58, 0x001e58},
+ {0x001e5a, 0x001e5a},
+ {0x001e5c, 0x001e5c},
+ {0x001e5e, 0x001e5e},
+ {0x001e60, 0x001e60},
+ {0x001e62, 0x001e62},
+ {0x001e64, 0x001e64},
+ {0x001e66, 0x001e66},
+ {0x001e68, 0x001e68},
+ {0x001e6a, 0x001e6a},
+ {0x001e6c, 0x001e6c},
+ {0x001e6e, 0x001e6e},
+ {0x001e70, 0x001e70},
+ {0x001e72, 0x001e72},
+ {0x001e74, 0x001e74},
+ {0x001e76, 0x001e76},
+ {0x001e78, 0x001e78},
+ {0x001e7a, 0x001e7a},
+ {0x001e7c, 0x001e7c},
+ {0x001e7e, 0x001e7e},
+ {0x001e80, 0x001e80},
+ {0x001e82, 0x001e82},
+ {0x001e84, 0x001e84},
+ {0x001e86, 0x001e86},
+ {0x001e88, 0x001e88},
+ {0x001e8a, 0x001e8a},
+ {0x001e8c, 0x001e8c},
+ {0x001e8e, 0x001e8e},
+ {0x001e90, 0x001e90},
+ {0x001e92, 0x001e92},
+ {0x001e94, 0x001e94},
+ {0x001e9e, 0x001e9e},
+ {0x001ea0, 0x001ea0},
+ {0x001ea2, 0x001ea2},
+ {0x001ea4, 0x001ea4},
+ {0x001ea6, 0x001ea6},
+ {0x001ea8, 0x001ea8},
+ {0x001eaa, 0x001eaa},
+ {0x001eac, 0x001eac},
+ {0x001eae, 0x001eae},
+ {0x001eb0, 0x001eb0},
+ {0x001eb2, 0x001eb2},
+ {0x001eb4, 0x001eb4},
+ {0x001eb6, 0x001eb6},
+ {0x001eb8, 0x001eb8},
+ {0x001eba, 0x001eba},
+ {0x001ebc, 0x001ebc},
+ {0x001ebe, 0x001ebe},
+ {0x001ec0, 0x001ec0},
+ {0x001ec2, 0x001ec2},
+ {0x001ec4, 0x001ec4},
+ {0x001ec6, 0x001ec6},
+ {0x001ec8, 0x001ec8},
+ {0x001eca, 0x001eca},
+ {0x001ecc, 0x001ecc},
+ {0x001ece, 0x001ece},
+ {0x001ed0, 0x001ed0},
+ {0x001ed2, 0x001ed2},
+ {0x001ed4, 0x001ed4},
+ {0x001ed6, 0x001ed6},
+ {0x001ed8, 0x001ed8},
+ {0x001eda, 0x001eda},
+ {0x001edc, 0x001edc},
+ {0x001ede, 0x001ede},
+ {0x001ee0, 0x001ee0},
+ {0x001ee2, 0x001ee2},
+ {0x001ee4, 0x001ee4},
+ {0x001ee6, 0x001ee6},
+ {0x001ee8, 0x001ee8},
+ {0x001eea, 0x001eea},
+ {0x001eec, 0x001eec},
+ {0x001eee, 0x001eee},
+ {0x001ef0, 0x001ef0},
+ {0x001ef2, 0x001ef2},
+ {0x001ef4, 0x001ef4},
+ {0x001ef6, 0x001ef6},
+ {0x001ef8, 0x001ef8},
+ {0x001efa, 0x001efa},
+ {0x001efc, 0x001efc},
+ {0x001efe, 0x001efe},
+ {0x001f08, 0x001f0f},
+ {0x001f18, 0x001f1d},
+ {0x001f28, 0x001f2f},
+ {0x001f38, 0x001f3f},
+ {0x001f48, 0x001f4d},
+ {0x001f59, 0x001f59},
+ {0x001f5b, 0x001f5b},
+ {0x001f5d, 0x001f5d},
+ {0x001f5f, 0x001f5f},
+ {0x001f68, 0x001f6f},
+ {0x001fb8, 0x001fbb},
+ {0x001fc8, 0x001fcb},
+ {0x001fd8, 0x001fdb},
+ {0x001fe8, 0x001fec},
+ {0x001ff8, 0x001ffb},
+ {0x002102, 0x002102},
+ {0x002107, 0x002107},
+ {0x00210b, 0x00210d},
+ {0x002110, 0x002112},
+ {0x002115, 0x002115},
+ {0x002119, 0x00211d},
+ {0x002124, 0x002124},
+ {0x002126, 0x002126},
+ {0x002128, 0x002128},
+ {0x00212a, 0x00212d},
+ {0x002130, 0x002133},
+ {0x00213e, 0x00213f},
+ {0x002145, 0x002145},
+ {0x002160, 0x00216f},
+ {0x002183, 0x002183},
+ {0x0024b6, 0x0024cf},
+ {0x002c00, 0x002c2f},
+ {0x002c60, 0x002c60},
+ {0x002c62, 0x002c64},
+ {0x002c67, 0x002c67},
+ {0x002c69, 0x002c69},
+ {0x002c6b, 0x002c6b},
+ {0x002c6d, 0x002c70},
+ {0x002c72, 0x002c72},
+ {0x002c75, 0x002c75},
+ {0x002c7e, 0x002c80},
+ {0x002c82, 0x002c82},
+ {0x002c84, 0x002c84},
+ {0x002c86, 0x002c86},
+ {0x002c88, 0x002c88},
+ {0x002c8a, 0x002c8a},
+ {0x002c8c, 0x002c8c},
+ {0x002c8e, 0x002c8e},
+ {0x002c90, 0x002c90},
+ {0x002c92, 0x002c92},
+ {0x002c94, 0x002c94},
+ {0x002c96, 0x002c96},
+ {0x002c98, 0x002c98},
+ {0x002c9a, 0x002c9a},
+ {0x002c9c, 0x002c9c},
+ {0x002c9e, 0x002c9e},
+ {0x002ca0, 0x002ca0},
+ {0x002ca2, 0x002ca2},
+ {0x002ca4, 0x002ca4},
+ {0x002ca6, 0x002ca6},
+ {0x002ca8, 0x002ca8},
+ {0x002caa, 0x002caa},
+ {0x002cac, 0x002cac},
+ {0x002cae, 0x002cae},
+ {0x002cb0, 0x002cb0},
+ {0x002cb2, 0x002cb2},
+ {0x002cb4, 0x002cb4},
+ {0x002cb6, 0x002cb6},
+ {0x002cb8, 0x002cb8},
+ {0x002cba, 0x002cba},
+ {0x002cbc, 0x002cbc},
+ {0x002cbe, 0x002cbe},
+ {0x002cc0, 0x002cc0},
+ {0x002cc2, 0x002cc2},
+ {0x002cc4, 0x002cc4},
+ {0x002cc6, 0x002cc6},
+ {0x002cc8, 0x002cc8},
+ {0x002cca, 0x002cca},
+ {0x002ccc, 0x002ccc},
+ {0x002cce, 0x002cce},
+ {0x002cd0, 0x002cd0},
+ {0x002cd2, 0x002cd2},
+ {0x002cd4, 0x002cd4},
+ {0x002cd6, 0x002cd6},
+ {0x002cd8, 0x002cd8},
+ {0x002cda, 0x002cda},
+ {0x002cdc, 0x002cdc},
+ {0x002cde, 0x002cde},
+ {0x002ce0, 0x002ce0},
+ {0x002ce2, 0x002ce2},
+ {0x002ceb, 0x002ceb},
+ {0x002ced, 0x002ced},
+ {0x002cf2, 0x002cf2},
+ {0x00a640, 0x00a640},
+ {0x00a642, 0x00a642},
+ {0x00a644, 0x00a644},
+ {0x00a646, 0x00a646},
+ {0x00a648, 0x00a648},
+ {0x00a64a, 0x00a64a},
+ {0x00a64c, 0x00a64c},
+ {0x00a64e, 0x00a64e},
+ {0x00a650, 0x00a650},
+ {0x00a652, 0x00a652},
+ {0x00a654, 0x00a654},
+ {0x00a656, 0x00a656},
+ {0x00a658, 0x00a658},
+ {0x00a65a, 0x00a65a},
+ {0x00a65c, 0x00a65c},
+ {0x00a65e, 0x00a65e},
+ {0x00a660, 0x00a660},
+ {0x00a662, 0x00a662},
+ {0x00a664, 0x00a664},
+ {0x00a666, 0x00a666},
+ {0x00a668, 0x00a668},
+ {0x00a66a, 0x00a66a},
+ {0x00a66c, 0x00a66c},
+ {0x00a680, 0x00a680},
+ {0x00a682, 0x00a682},
+ {0x00a684, 0x00a684},
+ {0x00a686, 0x00a686},
+ {0x00a688, 0x00a688},
+ {0x00a68a, 0x00a68a},
+ {0x00a68c, 0x00a68c},
+ {0x00a68e, 0x00a68e},
+ {0x00a690, 0x00a690},
+ {0x00a692, 0x00a692},
+ {0x00a694, 0x00a694},
+ {0x00a696, 0x00a696},
+ {0x00a698, 0x00a698},
+ {0x00a69a, 0x00a69a},
+ {0x00a722, 0x00a722},
+ {0x00a724, 0x00a724},
+ {0x00a726, 0x00a726},
+ {0x00a728, 0x00a728},
+ {0x00a72a, 0x00a72a},
+ {0x00a72c, 0x00a72c},
+ {0x00a72e, 0x00a72e},
+ {0x00a732, 0x00a732},
+ {0x00a734, 0x00a734},
+ {0x00a736, 0x00a736},
+ {0x00a738, 0x00a738},
+ {0x00a73a, 0x00a73a},
+ {0x00a73c, 0x00a73c},
+ {0x00a73e, 0x00a73e},
+ {0x00a740, 0x00a740},
+ {0x00a742, 0x00a742},
+ {0x00a744, 0x00a744},
+ {0x00a746, 0x00a746},
+ {0x00a748, 0x00a748},
+ {0x00a74a, 0x00a74a},
+ {0x00a74c, 0x00a74c},
+ {0x00a74e, 0x00a74e},
+ {0x00a750, 0x00a750},
+ {0x00a752, 0x00a752},
+ {0x00a754, 0x00a754},
+ {0x00a756, 0x00a756},
+ {0x00a758, 0x00a758},
+ {0x00a75a, 0x00a75a},
+ {0x00a75c, 0x00a75c},
+ {0x00a75e, 0x00a75e},
+ {0x00a760, 0x00a760},
+ {0x00a762, 0x00a762},
+ {0x00a764, 0x00a764},
+ {0x00a766, 0x00a766},
+ {0x00a768, 0x00a768},
+ {0x00a76a, 0x00a76a},
+ {0x00a76c, 0x00a76c},
+ {0x00a76e, 0x00a76e},
+ {0x00a779, 0x00a779},
+ {0x00a77b, 0x00a77b},
+ {0x00a77d, 0x00a77e},
+ {0x00a780, 0x00a780},
+ {0x00a782, 0x00a782},
+ {0x00a784, 0x00a784},
+ {0x00a786, 0x00a786},
+ {0x00a78b, 0x00a78b},
+ {0x00a78d, 0x00a78d},
+ {0x00a790, 0x00a790},
+ {0x00a792, 0x00a792},
+ {0x00a796, 0x00a796},
+ {0x00a798, 0x00a798},
+ {0x00a79a, 0x00a79a},
+ {0x00a79c, 0x00a79c},
+ {0x00a79e, 0x00a79e},
+ {0x00a7a0, 0x00a7a0},
+ {0x00a7a2, 0x00a7a2},
+ {0x00a7a4, 0x00a7a4},
+ {0x00a7a6, 0x00a7a6},
+ {0x00a7a8, 0x00a7a8},
+ {0x00a7aa, 0x00a7ae},
+ {0x00a7b0, 0x00a7b4},
+ {0x00a7b6, 0x00a7b6},
+ {0x00a7b8, 0x00a7b8},
+ {0x00a7ba, 0x00a7ba},
+ {0x00a7bc, 0x00a7bc},
+ {0x00a7be, 0x00a7be},
+ {0x00a7c0, 0x00a7c0},
+ {0x00a7c2, 0x00a7c2},
+ {0x00a7c4, 0x00a7c7},
+ {0x00a7c9, 0x00a7c9},
+ {0x00a7d0, 0x00a7d0},
+ {0x00a7d6, 0x00a7d6},
+ {0x00a7d8, 0x00a7d8},
+ {0x00a7f5, 0x00a7f5},
+ {0x00ff21, 0x00ff3a},
+ {0x010400, 0x010427},
+ {0x0104b0, 0x0104d3},
+ {0x010570, 0x01057a},
+ {0x01057c, 0x01058a},
+ {0x01058c, 0x010592},
+ {0x010594, 0x010595},
+ {0x010c80, 0x010cb2},
+ {0x0118a0, 0x0118bf},
+ {0x016e40, 0x016e5f},
+ {0x01d400, 0x01d419},
+ {0x01d434, 0x01d44d},
+ {0x01d468, 0x01d481},
+ {0x01d49c, 0x01d49c},
+ {0x01d49e, 0x01d49f},
+ {0x01d4a2, 0x01d4a2},
+ {0x01d4a5, 0x01d4a6},
+ {0x01d4a9, 0x01d4ac},
+ {0x01d4ae, 0x01d4b5},
+ {0x01d4d0, 0x01d4e9},
+ {0x01d504, 0x01d505},
+ {0x01d507, 0x01d50a},
+ {0x01d50d, 0x01d514},
+ {0x01d516, 0x01d51c},
+ {0x01d538, 0x01d539},
+ {0x01d53b, 0x01d53e},
+ {0x01d540, 0x01d544},
+ {0x01d546, 0x01d546},
+ {0x01d54a, 0x01d550},
+ {0x01d56c, 0x01d585},
+ {0x01d5a0, 0x01d5b9},
+ {0x01d5d4, 0x01d5ed},
+ {0x01d608, 0x01d621},
+ {0x01d63c, 0x01d655},
+ {0x01d670, 0x01d689},
+ {0x01d6a8, 0x01d6c0},
+ {0x01d6e2, 0x01d6fa},
+ {0x01d71c, 0x01d734},
+ {0x01d756, 0x01d76e},
+ {0x01d790, 0x01d7a8},
+ {0x01d7ca, 0x01d7ca},
+ {0x01e900, 0x01e921},
+ {0x01f130, 0x01f149},
+ {0x01f150, 0x01f169},
+ {0x01f170, 0x01f189},
+};
+
+/* table of Unicode codepoint ranges of Case_Ignorable characters */
+static const pg_unicode_range unicode_case_ignorable[491] =
+{
+ {0x000027, 0x000027},
+ {0x00002e, 0x00002e},
+ {0x00003a, 0x00003a},
+ {0x00005e, 0x00005e},
+ {0x000060, 0x000060},
+ {0x0000a8, 0x0000a8},
+ {0x0000ad, 0x0000ad},
+ {0x0000af, 0x0000af},
+ {0x0000b4, 0x0000b4},
+ {0x0000b7, 0x0000b7},
+ {0x0000b8, 0x0000b8},
+ {0x0002b0, 0x0002c1},
+ {0x0002c2, 0x0002c5},
+ {0x0002c6, 0x0002d1},
+ {0x0002d2, 0x0002df},
+ {0x0002e0, 0x0002e4},
+ {0x0002e5, 0x0002eb},
+ {0x0002ec, 0x0002ec},
+ {0x0002ed, 0x0002ed},
+ {0x0002ee, 0x0002ee},
+ {0x0002ef, 0x0002ff},
+ {0x000300, 0x00036f},
+ {0x000374, 0x000374},
+ {0x000375, 0x000375},
+ {0x00037a, 0x00037a},
+ {0x000384, 0x000385},
+ {0x000387, 0x000387},
+ {0x000483, 0x000487},
+ {0x000488, 0x000489},
+ {0x000559, 0x000559},
+ {0x00055f, 0x00055f},
+ {0x000591, 0x0005bd},
+ {0x0005bf, 0x0005bf},
+ {0x0005c1, 0x0005c2},
+ {0x0005c4, 0x0005c5},
+ {0x0005c7, 0x0005c7},
+ {0x0005f4, 0x0005f4},
+ {0x000600, 0x000605},
+ {0x000610, 0x00061a},
+ {0x00061c, 0x00061c},
+ {0x000640, 0x000640},
+ {0x00064b, 0x00065f},
+ {0x000670, 0x000670},
+ {0x0006d6, 0x0006dc},
+ {0x0006dd, 0x0006dd},
+ {0x0006df, 0x0006e4},
+ {0x0006e5, 0x0006e6},
+ {0x0006e7, 0x0006e8},
+ {0x0006ea, 0x0006ed},
+ {0x00070f, 0x00070f},
+ {0x000711, 0x000711},
+ {0x000730, 0x00074a},
+ {0x0007a6, 0x0007b0},
+ {0x0007eb, 0x0007f3},
+ {0x0007f4, 0x0007f5},
+ {0x0007fa, 0x0007fa},
+ {0x0007fd, 0x0007fd},
+ {0x000816, 0x000819},
+ {0x00081a, 0x00081a},
+ {0x00081b, 0x000823},
+ {0x000824, 0x000824},
+ {0x000825, 0x000827},
+ {0x000828, 0x000828},
+ {0x000829, 0x00082d},
+ {0x000859, 0x00085b},
+ {0x000888, 0x000888},
+ {0x000890, 0x000891},
+ {0x000898, 0x00089f},
+ {0x0008c9, 0x0008c9},
+ {0x0008ca, 0x0008e1},
+ {0x0008e2, 0x0008e2},
+ {0x0008e3, 0x000902},
+ {0x00093a, 0x00093a},
+ {0x00093c, 0x00093c},
+ {0x000941, 0x000948},
+ {0x00094d, 0x00094d},
+ {0x000951, 0x000957},
+ {0x000962, 0x000963},
+ {0x000971, 0x000971},
+ {0x000981, 0x000981},
+ {0x0009bc, 0x0009bc},
+ {0x0009c1, 0x0009c4},
+ {0x0009cd, 0x0009cd},
+ {0x0009e2, 0x0009e3},
+ {0x0009fe, 0x0009fe},
+ {0x000a01, 0x000a02},
+ {0x000a3c, 0x000a3c},
+ {0x000a41, 0x000a42},
+ {0x000a47, 0x000a48},
+ {0x000a4b, 0x000a4d},
+ {0x000a51, 0x000a51},
+ {0x000a70, 0x000a71},
+ {0x000a75, 0x000a75},
+ {0x000a81, 0x000a82},
+ {0x000abc, 0x000abc},
+ {0x000ac1, 0x000ac5},
+ {0x000ac7, 0x000ac8},
+ {0x000acd, 0x000acd},
+ {0x000ae2, 0x000ae3},
+ {0x000afa, 0x000aff},
+ {0x000b01, 0x000b01},
+ {0x000b3c, 0x000b3c},
+ {0x000b3f, 0x000b3f},
+ {0x000b41, 0x000b44},
+ {0x000b4d, 0x000b4d},
+ {0x000b55, 0x000b56},
+ {0x000b62, 0x000b63},
+ {0x000b82, 0x000b82},
+ {0x000bc0, 0x000bc0},
+ {0x000bcd, 0x000bcd},
+ {0x000c00, 0x000c00},
+ {0x000c04, 0x000c04},
+ {0x000c3c, 0x000c3c},
+ {0x000c3e, 0x000c40},
+ {0x000c46, 0x000c48},
+ {0x000c4a, 0x000c4d},
+ {0x000c55, 0x000c56},
+ {0x000c62, 0x000c63},
+ {0x000c81, 0x000c81},
+ {0x000cbc, 0x000cbc},
+ {0x000cbf, 0x000cbf},
+ {0x000cc6, 0x000cc6},
+ {0x000ccc, 0x000ccd},
+ {0x000ce2, 0x000ce3},
+ {0x000d00, 0x000d01},
+ {0x000d3b, 0x000d3c},
+ {0x000d41, 0x000d44},
+ {0x000d4d, 0x000d4d},
+ {0x000d62, 0x000d63},
+ {0x000d81, 0x000d81},
+ {0x000dca, 0x000dca},
+ {0x000dd2, 0x000dd4},
+ {0x000dd6, 0x000dd6},
+ {0x000e31, 0x000e31},
+ {0x000e34, 0x000e3a},
+ {0x000e46, 0x000e46},
+ {0x000e47, 0x000e4e},
+ {0x000eb1, 0x000eb1},
+ {0x000eb4, 0x000ebc},
+ {0x000ec6, 0x000ec6},
+ {0x000ec8, 0x000ece},
+ {0x000f18, 0x000f19},
+ {0x000f35, 0x000f35},
+ {0x000f37, 0x000f37},
+ {0x000f39, 0x000f39},
+ {0x000f71, 0x000f7e},
+ {0x000f80, 0x000f84},
+ {0x000f86, 0x000f87},
+ {0x000f8d, 0x000f97},
+ {0x000f99, 0x000fbc},
+ {0x000fc6, 0x000fc6},
+ {0x00102d, 0x001030},
+ {0x001032, 0x001037},
+ {0x001039, 0x00103a},
+ {0x00103d, 0x00103e},
+ {0x001058, 0x001059},
+ {0x00105e, 0x001060},
+ {0x001071, 0x001074},
+ {0x001082, 0x001082},
+ {0x001085, 0x001086},
+ {0x00108d, 0x00108d},
+ {0x00109d, 0x00109d},
+ {0x0010fc, 0x0010fc},
+ {0x00135d, 0x00135f},
+ {0x001712, 0x001714},
+ {0x001732, 0x001733},
+ {0x001752, 0x001753},
+ {0x001772, 0x001773},
+ {0x0017b4, 0x0017b5},
+ {0x0017b7, 0x0017bd},
+ {0x0017c6, 0x0017c6},
+ {0x0017c9, 0x0017d3},
+ {0x0017d7, 0x0017d7},
+ {0x0017dd, 0x0017dd},
+ {0x00180b, 0x00180d},
+ {0x00180e, 0x00180e},
+ {0x00180f, 0x00180f},
+ {0x001843, 0x001843},
+ {0x001885, 0x001886},
+ {0x0018a9, 0x0018a9},
+ {0x001920, 0x001922},
+ {0x001927, 0x001928},
+ {0x001932, 0x001932},
+ {0x001939, 0x00193b},
+ {0x001a17, 0x001a18},
+ {0x001a1b, 0x001a1b},
+ {0x001a56, 0x001a56},
+ {0x001a58, 0x001a5e},
+ {0x001a60, 0x001a60},
+ {0x001a62, 0x001a62},
+ {0x001a65, 0x001a6c},
+ {0x001a73, 0x001a7c},
+ {0x001a7f, 0x001a7f},
+ {0x001aa7, 0x001aa7},
+ {0x001ab0, 0x001abd},
+ {0x001abe, 0x001abe},
+ {0x001abf, 0x001ace},
+ {0x001b00, 0x001b03},
+ {0x001b34, 0x001b34},
+ {0x001b36, 0x001b3a},
+ {0x001b3c, 0x001b3c},
+ {0x001b42, 0x001b42},
+ {0x001b6b, 0x001b73},
+ {0x001b80, 0x001b81},
+ {0x001ba2, 0x001ba5},
+ {0x001ba8, 0x001ba9},
+ {0x001bab, 0x001bad},
+ {0x001be6, 0x001be6},
+ {0x001be8, 0x001be9},
+ {0x001bed, 0x001bed},
+ {0x001bef, 0x001bf1},
+ {0x001c2c, 0x001c33},
+ {0x001c36, 0x001c37},
+ {0x001c78, 0x001c7d},
+ {0x001cd0, 0x001cd2},
+ {0x001cd4, 0x001ce0},
+ {0x001ce2, 0x001ce8},
+ {0x001ced, 0x001ced},
+ {0x001cf4, 0x001cf4},
+ {0x001cf8, 0x001cf9},
+ {0x001d2c, 0x001d6a},
+ {0x001d78, 0x001d78},
+ {0x001d9b, 0x001dbf},
+ {0x001dc0, 0x001dff},
+ {0x001fbd, 0x001fbd},
+ {0x001fbf, 0x001fc1},
+ {0x001fcd, 0x001fcf},
+ {0x001fdd, 0x001fdf},
+ {0x001fed, 0x001fef},
+ {0x001ffd, 0x001ffe},
+ {0x00200b, 0x00200f},
+ {0x002018, 0x002018},
+ {0x002019, 0x002019},
+ {0x002024, 0x002024},
+ {0x002027, 0x002027},
+ {0x00202a, 0x00202e},
+ {0x002060, 0x002064},
+ {0x002066, 0x00206f},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x0020d0, 0x0020dc},
+ {0x0020dd, 0x0020e0},
+ {0x0020e1, 0x0020e1},
+ {0x0020e2, 0x0020e4},
+ {0x0020e5, 0x0020f0},
+ {0x002c7c, 0x002c7d},
+ {0x002cef, 0x002cf1},
+ {0x002d6f, 0x002d6f},
+ {0x002d7f, 0x002d7f},
+ {0x002de0, 0x002dff},
+ {0x002e2f, 0x002e2f},
+ {0x003005, 0x003005},
+ {0x00302a, 0x00302d},
+ {0x003031, 0x003035},
+ {0x00303b, 0x00303b},
+ {0x003099, 0x00309a},
+ {0x00309b, 0x00309c},
+ {0x00309d, 0x00309e},
+ {0x0030fc, 0x0030fe},
+ {0x00a015, 0x00a015},
+ {0x00a4f8, 0x00a4fd},
+ {0x00a60c, 0x00a60c},
+ {0x00a66f, 0x00a66f},
+ {0x00a670, 0x00a672},
+ {0x00a674, 0x00a67d},
+ {0x00a67f, 0x00a67f},
+ {0x00a69c, 0x00a69d},
+ {0x00a69e, 0x00a69f},
+ {0x00a6f0, 0x00a6f1},
+ {0x00a700, 0x00a716},
+ {0x00a717, 0x00a71f},
+ {0x00a720, 0x00a721},
+ {0x00a770, 0x00a770},
+ {0x00a788, 0x00a788},
+ {0x00a789, 0x00a78a},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a802, 0x00a802},
+ {0x00a806, 0x00a806},
+ {0x00a80b, 0x00a80b},
+ {0x00a825, 0x00a826},
+ {0x00a82c, 0x00a82c},
+ {0x00a8c4, 0x00a8c5},
+ {0x00a8e0, 0x00a8f1},
+ {0x00a8ff, 0x00a8ff},
+ {0x00a926, 0x00a92d},
+ {0x00a947, 0x00a951},
+ {0x00a980, 0x00a982},
+ {0x00a9b3, 0x00a9b3},
+ {0x00a9b6, 0x00a9b9},
+ {0x00a9bc, 0x00a9bd},
+ {0x00a9cf, 0x00a9cf},
+ {0x00a9e5, 0x00a9e5},
+ {0x00a9e6, 0x00a9e6},
+ {0x00aa29, 0x00aa2e},
+ {0x00aa31, 0x00aa32},
+ {0x00aa35, 0x00aa36},
+ {0x00aa43, 0x00aa43},
+ {0x00aa4c, 0x00aa4c},
+ {0x00aa70, 0x00aa70},
+ {0x00aa7c, 0x00aa7c},
+ {0x00aab0, 0x00aab0},
+ {0x00aab2, 0x00aab4},
+ {0x00aab7, 0x00aab8},
+ {0x00aabe, 0x00aabf},
+ {0x00aac1, 0x00aac1},
+ {0x00aadd, 0x00aadd},
+ {0x00aaec, 0x00aaed},
+ {0x00aaf3, 0x00aaf4},
+ {0x00aaf6, 0x00aaf6},
+ {0x00ab5b, 0x00ab5b},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab69, 0x00ab69},
+ {0x00ab6a, 0x00ab6b},
+ {0x00abe5, 0x00abe5},
+ {0x00abe8, 0x00abe8},
+ {0x00abed, 0x00abed},
+ {0x00fb1e, 0x00fb1e},
+ {0x00fbb2, 0x00fbc2},
+ {0x00fe00, 0x00fe0f},
+ {0x00fe13, 0x00fe13},
+ {0x00fe20, 0x00fe2f},
+ {0x00fe52, 0x00fe52},
+ {0x00fe55, 0x00fe55},
+ {0x00feff, 0x00feff},
+ {0x00ff07, 0x00ff07},
+ {0x00ff0e, 0x00ff0e},
+ {0x00ff1a, 0x00ff1a},
+ {0x00ff3e, 0x00ff3e},
+ {0x00ff40, 0x00ff40},
+ {0x00ff70, 0x00ff70},
+ {0x00ff9e, 0x00ff9f},
+ {0x00ffe3, 0x00ffe3},
+ {0x00fff9, 0x00fffb},
+ {0x0101fd, 0x0101fd},
+ {0x0102e0, 0x0102e0},
+ {0x010376, 0x01037a},
+ {0x010780, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010a01, 0x010a03},
+ {0x010a05, 0x010a06},
+ {0x010a0c, 0x010a0f},
+ {0x010a38, 0x010a3a},
+ {0x010a3f, 0x010a3f},
+ {0x010ae5, 0x010ae6},
+ {0x010d24, 0x010d27},
+ {0x010eab, 0x010eac},
+ {0x010efd, 0x010eff},
+ {0x010f46, 0x010f50},
+ {0x010f82, 0x010f85},
+ {0x011001, 0x011001},
+ {0x011038, 0x011046},
+ {0x011070, 0x011070},
+ {0x011073, 0x011074},
+ {0x01107f, 0x011081},
+ {0x0110b3, 0x0110b6},
+ {0x0110b9, 0x0110ba},
+ {0x0110bd, 0x0110bd},
+ {0x0110c2, 0x0110c2},
+ {0x0110cd, 0x0110cd},
+ {0x011100, 0x011102},
+ {0x011127, 0x01112b},
+ {0x01112d, 0x011134},
+ {0x011173, 0x011173},
+ {0x011180, 0x011181},
+ {0x0111b6, 0x0111be},
+ {0x0111c9, 0x0111cc},
+ {0x0111cf, 0x0111cf},
+ {0x01122f, 0x011231},
+ {0x011234, 0x011234},
+ {0x011236, 0x011237},
+ {0x01123e, 0x01123e},
+ {0x011241, 0x011241},
+ {0x0112df, 0x0112df},
+ {0x0112e3, 0x0112ea},
+ {0x011300, 0x011301},
+ {0x01133b, 0x01133c},
+ {0x011340, 0x011340},
+ {0x011366, 0x01136c},
+ {0x011370, 0x011374},
+ {0x011438, 0x01143f},
+ {0x011442, 0x011444},
+ {0x011446, 0x011446},
+ {0x01145e, 0x01145e},
+ {0x0114b3, 0x0114b8},
+ {0x0114ba, 0x0114ba},
+ {0x0114bf, 0x0114c0},
+ {0x0114c2, 0x0114c3},
+ {0x0115b2, 0x0115b5},
+ {0x0115bc, 0x0115bd},
+ {0x0115bf, 0x0115c0},
+ {0x0115dc, 0x0115dd},
+ {0x011633, 0x01163a},
+ {0x01163d, 0x01163d},
+ {0x01163f, 0x011640},
+ {0x0116ab, 0x0116ab},
+ {0x0116ad, 0x0116ad},
+ {0x0116b0, 0x0116b5},
+ {0x0116b7, 0x0116b7},
+ {0x01171d, 0x01171f},
+ {0x011722, 0x011725},
+ {0x011727, 0x01172b},
+ {0x01182f, 0x011837},
+ {0x011839, 0x01183a},
+ {0x01193b, 0x01193c},
+ {0x01193e, 0x01193e},
+ {0x011943, 0x011943},
+ {0x0119d4, 0x0119d7},
+ {0x0119da, 0x0119db},
+ {0x0119e0, 0x0119e0},
+ {0x011a01, 0x011a0a},
+ {0x011a33, 0x011a38},
+ {0x011a3b, 0x011a3e},
+ {0x011a47, 0x011a47},
+ {0x011a51, 0x011a56},
+ {0x011a59, 0x011a5b},
+ {0x011a8a, 0x011a96},
+ {0x011a98, 0x011a99},
+ {0x011c30, 0x011c36},
+ {0x011c38, 0x011c3d},
+ {0x011c3f, 0x011c3f},
+ {0x011c92, 0x011ca7},
+ {0x011caa, 0x011cb0},
+ {0x011cb2, 0x011cb3},
+ {0x011cb5, 0x011cb6},
+ {0x011d31, 0x011d36},
+ {0x011d3a, 0x011d3a},
+ {0x011d3c, 0x011d3d},
+ {0x011d3f, 0x011d45},
+ {0x011d47, 0x011d47},
+ {0x011d90, 0x011d91},
+ {0x011d95, 0x011d95},
+ {0x011d97, 0x011d97},
+ {0x011ef3, 0x011ef4},
+ {0x011f00, 0x011f01},
+ {0x011f36, 0x011f3a},
+ {0x011f40, 0x011f40},
+ {0x011f42, 0x011f42},
+ {0x013430, 0x01343f},
+ {0x013440, 0x013440},
+ {0x013447, 0x013455},
+ {0x016af0, 0x016af4},
+ {0x016b30, 0x016b36},
+ {0x016b40, 0x016b43},
+ {0x016f4f, 0x016f4f},
+ {0x016f8f, 0x016f92},
+ {0x016f93, 0x016f9f},
+ {0x016fe0, 0x016fe1},
+ {0x016fe3, 0x016fe3},
+ {0x016fe4, 0x016fe4},
+ {0x01aff0, 0x01aff3},
+ {0x01aff5, 0x01affb},
+ {0x01affd, 0x01affe},
+ {0x01bc9d, 0x01bc9e},
+ {0x01bca0, 0x01bca3},
+ {0x01cf00, 0x01cf2d},
+ {0x01cf30, 0x01cf46},
+ {0x01d167, 0x01d169},
+ {0x01d173, 0x01d17a},
+ {0x01d17b, 0x01d182},
+ {0x01d185, 0x01d18b},
+ {0x01d1aa, 0x01d1ad},
+ {0x01d242, 0x01d244},
+ {0x01da00, 0x01da36},
+ {0x01da3b, 0x01da6c},
+ {0x01da75, 0x01da75},
+ {0x01da84, 0x01da84},
+ {0x01da9b, 0x01da9f},
+ {0x01daa1, 0x01daaf},
+ {0x01e000, 0x01e006},
+ {0x01e008, 0x01e018},
+ {0x01e01b, 0x01e021},
+ {0x01e023, 0x01e024},
+ {0x01e026, 0x01e02a},
+ {0x01e030, 0x01e06d},
+ {0x01e08f, 0x01e08f},
+ {0x01e130, 0x01e136},
+ {0x01e137, 0x01e13d},
+ {0x01e2ae, 0x01e2ae},
+ {0x01e2ec, 0x01e2ef},
+ {0x01e4eb, 0x01e4eb},
+ {0x01e4ec, 0x01e4ef},
+ {0x01e8d0, 0x01e8d6},
+ {0x01e944, 0x01e94a},
+ {0x01e94b, 0x01e94b},
+ {0x01f3fb, 0x01f3ff},
+ {0x0e0001, 0x0e0001},
+ {0x0e0020, 0x0e007f},
+ {0x0e0100, 0x0e01ef},
+};
+
+/* table of Unicode codepoint ranges of White_Space characters */
+static const pg_unicode_range unicode_white_space[11] =
+{
+ {0x000009, 0x00000d},
+ {0x000020, 0x000020},
+ {0x000085, 0x000085},
+ {0x0000a0, 0x0000a0},
+ {0x001680, 0x001680},
+ {0x002000, 0x00200a},
+ {0x002028, 0x002028},
+ {0x002029, 0x002029},
+ {0x00202f, 0x00202f},
+ {0x00205f, 0x00205f},
+ {0x003000, 0x003000},
+};
+
+/* table of Unicode codepoint ranges of Hex_Digit characters */
+static const pg_unicode_range unicode_hex_digit[6] =
+{
+ {0x000030, 0x000039},
+ {0x000041, 0x000046},
+ {0x000061, 0x000066},
+ {0x00ff10, 0x00ff19},
+ {0x00ff21, 0x00ff26},
+ {0x00ff41, 0x00ff46},
+};
+
+/* table of Unicode codepoint ranges of Join_Control characters */
+static const pg_unicode_range unicode_join_control[1] =
+{
+ {0x00200c, 0x00200d},
};
--
2.34.1
[text/x-patch] v18-0003-Add-unicode-case-mapping-tables-and-functions.patch (311.6K, ../../[email protected]/4-v18-0003-Add-unicode-case-mapping-tables-and-functions.patch)
download | inline diff:
From 77a0b211624c78e9f20615decc1f1982ba2c2446 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 30 Oct 2023 17:38:54 -0700
Subject: [PATCH v18 3/6] Add unicode case mapping tables and functions.
---
src/common/Makefile | 1 +
src/common/meson.build | 1 +
src/common/unicode/Makefile | 15 +-
src/common/unicode/case_test.c | 100 +
.../unicode/generate-unicode_case_table.pl | 274 ++
src/common/unicode/meson.build | 33 +-
src/common/unicode_case.c | 242 ++
src/common/wchar.c | 4 +-
src/include/common/unicode_case.h | 31 +
src/include/common/unicode_case_table.h | 3175 +++++++++++++++++
src/include/mb/pg_wchar.h | 15 +
11 files changed, 3885 insertions(+), 6 deletions(-)
create mode 100644 src/common/unicode/case_test.c
create mode 100644 src/common/unicode/generate-unicode_case_table.pl
create mode 100644 src/common/unicode_case.c
create mode 100644 src/include/common/unicode_case.h
create mode 100644 src/include/common/unicode_case_table.h
diff --git a/src/common/Makefile b/src/common/Makefile
index 2ba5069dca..3d83299432 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -78,6 +78,7 @@ OBJS_COMMON = \
scram-common.o \
string.o \
stringinfo.o \
+ unicode_case.o \
unicode_category.o \
unicode_norm.o \
username.o \
diff --git a/src/common/meson.build b/src/common/meson.build
index 4eb16024cb..de68e408fa 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -32,6 +32,7 @@ common_sources = files(
'scram-common.c',
'string.c',
'stringinfo.c',
+ 'unicode_case.c',
'unicode_category.c',
'unicode_norm.c',
'username.c',
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index 27f0408d8b..6c3a275772 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -21,20 +21,24 @@ CPPFLAGS += $(ICU_CFLAGS)
# By default, do nothing.
all:
-update-unicode: unicode_category_table.h unicode_east_asian_fw_table.h unicode_nonspacing_table.h unicode_norm_hashfunc.h unicode_norm_table.h unicode_normprops_table.h unicode_version.h
+update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian_fw_table.h unicode_nonspacing_table.h unicode_norm_hashfunc.h unicode_norm_table.h unicode_normprops_table.h unicode_version.h
mv $^ $(top_srcdir)/src/include/common/
+ $(MAKE) case-check
$(MAKE) category-check
$(MAKE) normalization-check
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
$(PERL) $< --version $(UNICODE_VERSION)
+unicode_case_table.h: generate-unicode_case_table.pl UnicodeData.txt
+ $(PERL) $<
+
unicode_category_table.h: generate-unicode_category_table.pl DerivedCoreProperties.txt PropList.txt UnicodeData.txt
$(PERL) $<
@@ -55,12 +59,17 @@ unicode_normprops_table.h: generate-unicode_normprops_table.pl DerivedNormalizat
$(PERL) $^ >$@
# Test suite
+case-check: case_test
+ ./case_test
+
category-check: category_test
./category_test
normalization-check: norm_test
./norm_test
+case_test: case_test.o ../unicode_case.o | submake-common
+
category_test: category_test.o ../unicode_category.o | submake-common
norm_test: norm_test.o ../unicode_norm.o | submake-common
@@ -82,4 +91,4 @@ clean:
rm -f $(OBJS) category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/case_test.c b/src/common/unicode/case_test.c
new file mode 100644
index 0000000000..16b9a71ee6
--- /dev/null
+++ b/src/common/unicode/case_test.c
@@ -0,0 +1,100 @@
+/*-------------------------------------------------------------------------
+ * case_test.c
+ * Program to test Unicode case mapping functions.
+ *
+ * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/unicode/case_test.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres_fe.h"
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wctype.h>
+
+#ifdef USE_ICU
+#include <unicode/uchar.h>
+#endif
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
+#include "common/unicode_version.h"
+
+#ifdef USE_ICU
+
+static void
+icu_test_simple(pg_wchar code)
+{
+ pg_wchar lower = unicode_case_simple(code, CaseLower);
+ pg_wchar title = unicode_case_simple(code, CaseTitle);
+ pg_wchar upper = unicode_case_simple(code, CaseUpper);
+ pg_wchar iculower = u_tolower(code);
+ pg_wchar icutitle = u_totitle(code);
+ pg_wchar icuupper = u_toupper(code);
+
+ if (lower != iculower || title != icutitle || upper != icuupper)
+ {
+ printf("case_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("case_test: Postgres lower/title/upper: 0x%06x/0x%06x/0x%06x\n",
+ lower, title, upper);
+ printf("case_test: ICU lower/title/upper: 0x%06x/0x%06x/0x%06x\n",
+ iculower, icutitle, icuupper);
+ printf("\n");
+ exit(1);
+ }
+}
+
+static void
+test_icu(void)
+{
+ int successful = 0;
+ int skipped_mismatch = 0;
+
+ for (pg_wchar code = 0; code <= 0x10ffff; code++)
+ {
+ pg_unicode_category category = unicode_category(code);
+
+ if (category != PG_U_UNASSIGNED)
+ {
+ uint8_t icu_category = u_charType(code);
+
+ if (icu_category == PG_U_UNASSIGNED)
+ {
+ skipped_mismatch++;
+ continue;
+ }
+
+ icu_test_simple(code);
+ successful++;
+ }
+ }
+
+ if (skipped_mismatch > 0)
+ printf("case_test: skipped %d codepoints unassigned in ICU due to Unicode version mismatch\n",
+ skipped_mismatch);
+
+ printf("case_test: ICU simple mapping test: %d codepoints successful\n",
+ successful);
+}
+#endif
+
+/*
+ * Exhaustively compare case mappings with the results from libc and ICU.
+ */
+int
+main(int argc, char **argv)
+{
+ printf("case_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
+#ifdef USE_ICU
+ printf("case_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
+ test_icu();
+#else
+ printf("case_test: ICU not available; skipping\n");
+#endif
+
+ exit(0);
+}
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
new file mode 100644
index 0000000000..36893c9a31
--- /dev/null
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -0,0 +1,274 @@
+#!/usr/bin/perl
+#
+# Generate Unicode character case mappings. Does not include tailoring
+# or locale-specific mappings.
+#
+# Input: SpecialCasing.txt UnicodeData.txt
+# Output: unicode_case_table.h
+#
+# Copyright (c) 2000-2023, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+use FindBin;
+use lib "$FindBin::RealBin/../../tools/";
+
+my $output_path = '.';
+
+GetOptions('outdir:s' => \$output_path);
+
+my $output_table_file = "$output_path/unicode_case_table.h";
+
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
+my $FH;
+
+my %simple = ();
+
+open($FH, '<', "$output_path/UnicodeData.txt")
+ or die "Could not open $output_path/UnicodeData.txt: $!.";
+while (my $line = <$FH>)
+{
+ my @elts = split(';', $line);
+ my $code = hex($elts[0]);
+ my $simple_uppercase = hex($elts[12] =~ s/^\s+|\s+$//rg);
+ my $simple_lowercase = hex($elts[13] =~ s/^\s+|\s+$//rg);
+ my $simple_titlecase = hex($elts[14] =~ s/^\s+|\s+$//rg);
+
+ die "codepoint $code out of range" if $code > 0x10FFFF;
+ die "Simple_Lowercase $code out of range" if $simple_lowercase > 0x10FFFF;
+ die "Simple_Titlecase $code out of range" if $simple_titlecase > 0x10FFFF;
+ die "Simple_Uppercase $code out of range" if $simple_uppercase > 0x10FFFF;
+
+ if ($simple_lowercase || $simple_titlecase || $simple_uppercase)
+ {
+ $simple{$code} = {
+ Simple_Lowercase => ($simple_lowercase || $code),
+ Simple_Titlecase => ($simple_titlecase || $code),
+ Simple_Uppercase => ($simple_uppercase || $code)
+ };
+ }
+}
+close $FH;
+
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
+# Start writing out the output files
+open my $OT, '>', $output_table_file
+ or die "Could not open output file $output_table_file: $!\n";
+
+# determine size of array given that codepoints <= 0x80 are dense and
+# the rest of the entries are sparse
+my $num_simple = 0x80;
+foreach my $code (sort { $a <=> $b } (keys %simple))
+{
+ $num_simple++ unless $code < 0x80;
+}
+
+my $num_special = scalar(keys %special) + 1;
+
+print $OT <<"EOS";
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case_table.h
+ * Case mapping and information table.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/common/unicode_case_table.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * File auto-generated by src/common/unicode/generate-unicode_case_table.pl,
+ * do not edit. There is deliberately not an #ifndef PG_UNICODE_CASE_TABLE_H
+ * here.
+ */
+
+#include "common/unicode_case.h"
+#include "mb/pg_wchar.h"
+
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
+} pg_case_map;
+
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
+/*
+ * Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
+ * sparse for higher codepoints (requiring scan or binary search).
+ */
+static const pg_case_map case_map[$num_simple] =
+{
+EOS
+
+printf $OT "\t/* begin dense entries for codepoints < 0x80 */\n";
+for (my $code = 0; $code < 0x80; $code++)
+{
+ my $lc = ($simple{$code}{Simple_Lowercase} || $code);
+ my $tc = ($simple{$code}{Simple_Titlecase} || $code);
+ my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
+ printf $OT
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
+ $code, $lc, $tc, $uc;
+}
+printf $OT "\n";
+
+printf $OT "\t/* begin sparse entries for codepoints >= 0x80 */\n";
+foreach my $code (sort { $a <=> $b } (keys %simple))
+{
+ next unless $code >= 0x80; # already output above
+
+ my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
+ printf $OT
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
+ $code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
+ $map->{Simple_Uppercase}, $special_case;
+}
+print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index d7190bb8ca..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -24,6 +24,16 @@ endforeach
update_unicode_targets = []
+update_unicode_targets += \
+ custom_target('unicode_case_table.h',
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
+ output: ['unicode_case_table.h'],
+ command: [
+ perl, files('generate-unicode_case_table.pl'),
+ '--outdir', '@OUTDIR@', '@INPUT@'],
+ build_by_default: false,
+ )
+
update_unicode_targets += \
custom_target('unicode_category_table.h',
input: [unicode_data['UnicodeData.txt'], unicode_data['DerivedCoreProperties.txt'], unicode_data['PropList.txt']],
@@ -92,6 +102,17 @@ norm_test_table = custom_target('norm_test_table.h',
inc = include_directories('.')
+case_test = executable('case_test',
+ ['case_test.c'],
+ dependencies: [frontend_port_code, icu],
+ include_directories: inc,
+ link_with: [common_static, pgport_static],
+ build_by_default: false,
+ kwargs: default_bin_args + {
+ 'install': false,
+ }
+)
+
category_test = executable('category_test',
['category_test.c'],
dependencies: [frontend_port_code, icu],
@@ -116,6 +137,16 @@ norm_test = executable('norm_test',
update_unicode_dep = []
+if not meson.is_cross_build()
+ update_unicode_dep += custom_target('case_test.run',
+ output: 'case_test.run',
+ input: update_unicode_targets,
+ command: [case_test, UNICODE_VERSION],
+ build_by_default: false,
+ build_always_stale: true,
+ )
+endif
+
if not meson.is_cross_build()
update_unicode_dep += custom_target('category_test.run',
output: 'category_test.run',
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
new file mode 100644
index 0000000000..586068e780
--- /dev/null
+++ b/src/common/unicode_case.c
@@ -0,0 +1,242 @@
+/*-------------------------------------------------------------------------
+ * unicode_case.c
+ * Conversion to upper or lower case.
+ *
+ * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/unicode_case.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/unicode_case.h"
+#include "common/unicode_case_table.h"
+#include "common/unicode_category.h"
+#include "mb/pg_wchar.h"
+
+static const pg_case_map *find_case_map(pg_wchar ucs);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
+
+/* find entry in simple case map, if any */
+static const pg_case_map *
+find_case_map(pg_wchar ucs)
+{
+ int min = 0;
+ int mid;
+ int max = lengthof(case_map) - 1;
+
+ /* all chars <= 0x80 are stored in array for fast lookup */
+ Assert(max >= 0x7f);
+ if (ucs < 0x80)
+ {
+ const pg_case_map *map = &case_map[ucs];
+
+ Assert(map->codepoint == ucs);
+ return map;
+ }
+
+ /* otherwise, binary search */
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (ucs > case_map[mid].codepoint)
+ min = mid + 1;
+ else if (ucs < case_map[mid].codepoint)
+ max = mid - 1;
+ else
+ return &case_map[mid];
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Returns simple mapping for the given character, or the original character
+ * if none.
+ */
+pg_wchar
+unicode_case_simple(pg_wchar code, CaseKind casekind)
+{
+ const pg_case_map *map = find_case_map(code);
+
+ return map ? map->simplemap[casekind] : code;
+}
+
+/*
+ * Convert case of src, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ */
+size_t
+unicode_convert_case(char *dst, size_t dstsize, const char *src,
+ size_t srclen, CaseKind casekind, bool full)
+{
+ size_t srcoff = 0;
+ size_t result_len = 0;
+
+ /* not currently supported */
+ Assert(casekind != CaseTitle);
+
+ while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
+ {
+ pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
+ int u1len = unicode_utf8len(u1);
+ const pg_case_map *casemap = find_case_map(u1);
+ const pg_special_case *special = NULL;
+
+ /*
+ * Find special case that matches the conditions, if available.
+ *
+ * Only a single special mapping per codepoint is currently supported.
+ * Unicode allows for multiple special mappings for a single
+ * codepoint, so we may have a reason to support that in the future.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
+ if (special)
+ {
+ /* special mapping available */
+
+ Assert(special->codepoint == u1);
+
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
+ {
+ /* simple mapping available */
+
+ pg_wchar u2 = casemap->simplemap[casekind];
+ pg_wchar u2len = unicode_utf8len(u2);
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+ result_len += u2len;
+ }
+ else
+ {
+ /* no mapping; copy bytes from src */
+
+ if (result_len + u1len < dstsize)
+ memcpy(dst + result_len, src + srcoff, u1len);
+ result_len += u1len;
+ }
+
+ srcoff += u1len;
+ }
+
+ if (result_len < dstsize)
+ dst[result_len] = '\0';
+
+ return result_len;
+}
+
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
diff --git a/src/common/wchar.c b/src/common/wchar.c
index 7c5ce5ca08..95e6b499e3 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -477,8 +477,8 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
/*
- * Map a Unicode code point to UTF-8. utf8string must have 4 bytes of
- * space allocated.
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
*/
unsigned char *
unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
new file mode 100644
index 0000000000..13d561217b
--- /dev/null
+++ b/src/include/common/unicode_case.h
@@ -0,0 +1,31 @@
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case.h
+ * Routines for converting character case.
+ *
+ * These definitions can be used by both frontend and backend code.
+ *
+ * Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * src/include/common/unicode_case.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef UNICODE_CASE_H
+#define UNICODE_CASE_H
+
+#include "mb/pg_wchar.h"
+
+typedef enum
+{
+ CaseLower = 0,
+ CaseTitle = 1,
+ CaseUpper = 2,
+ NCaseKind
+} CaseKind;
+
+pg_wchar unicode_case_simple(pg_wchar ucs, CaseKind casekind);
+size_t unicode_convert_case(char *dst, size_t dstsize, const char *src,
+ size_t srclen, CaseKind casekind, bool full);
+
+#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
new file mode 100644
index 0000000000..e5b8850df7
--- /dev/null
+++ b/src/include/common/unicode_case_table.h
@@ -0,0 +1,3175 @@
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case_table.h
+ * Case mapping and information table.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/common/unicode_case_table.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * File auto-generated by src/common/unicode/generate-unicode_case_table.pl,
+ * do not edit. There is deliberately not an #ifndef PG_UNICODE_CASE_TABLE_H
+ * here.
+ */
+
+#include "common/unicode_case.h"
+#include "mb/pg_wchar.h"
+
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
+} pg_case_map;
+
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
+/*
+ * Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
+ * sparse for higher codepoints (requiring scan or binary search).
+ */
+static const pg_case_map case_map[3003] =
+{
+ /* begin dense entries for codepoints < 0x80 */
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
+
+ /* begin sparse entries for codepoints >= 0x80 */
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+};
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 1d521bea24..fbd9e58ed3 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -562,6 +562,21 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Number of bytes needed to represent the given char in UTF8.
+ */
+static inline int
+unicode_utf8len(pg_wchar c)
+{
+ if (c <= 0x7F)
+ return 1;
+ else if (c <= 0x7FF)
+ return 2;
+ else if (c <= 0xFFFF)
+ return 3;
+ else
+ return 4;
+}
/*
* The functions in this list are exported by libpq, and we need to be sure
--
2.34.1
[text/x-patch] v18-0004-Catalog-changes-preparing-for-builtin-collation-.patch (48.5K, ../../[email protected]/5-v18-0004-Catalog-changes-preparing-for-builtin-collation-.patch)
download | inline diff:
From 746a1a9d583f49343435e390289236e2cd199d23 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Tue, 26 Dec 2023 13:32:48 -0800
Subject: [PATCH v18 4/6] Catalog changes preparing for builtin collation
provider.
daticulocale -> datlocale, colliculocale -> colllocale.
---
doc/src/sgml/bki.sgml | 2 +-
doc/src/sgml/catalogs.sgml | 8 +--
src/backend/catalog/pg_collation.c | 10 +--
src/backend/commands/collationcmds.c | 34 +++++-----
src/backend/commands/dbcommands.c | 68 +++++++++----------
src/backend/utils/adt/pg_locale.c | 4 +-
src/backend/utils/init/postinit.c | 12 ++--
src/bin/initdb/initdb.c | 32 ++++-----
src/bin/pg_dump/pg_dump.c | 56 ++++++++-------
src/bin/pg_upgrade/info.c | 31 ++++++---
src/bin/pg_upgrade/pg_upgrade.c | 34 +++++++---
src/bin/pg_upgrade/pg_upgrade.h | 2 +-
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 27 +++++---
src/bin/psql/describe.c | 20 ++++--
src/include/catalog/pg_collation.dat | 2 +-
src/include/catalog/pg_collation.h | 4 +-
src/include/catalog/pg_database.dat | 2 +-
src/include/catalog/pg_database.h | 2 +-
.../regress/expected/collate.icu.utf8.out | 4 +-
src/test/regress/expected/psql.out | 18 ++---
src/test/regress/sql/collate.icu.utf8.sql | 4 +-
21 files changed, 211 insertions(+), 165 deletions(-)
diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 315ba81951..3cd5bee7ff 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -186,7 +186,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE', datacl => '_null_' },
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE', datacl => '_null_' },
]
]]></programlisting>
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 880f717b10..734b1cf74f 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2422,10 +2422,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>colliculocale</structfield> <type>text</type>
+ <structfield>colllocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this collation object
+ Locale name for builtin or ICU provider
</para></entry>
</row>
@@ -3131,10 +3131,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>daticulocale</structfield> <type>text</type>
+ <structfield>datlocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this database
+ Locale name for builtin or ICU provider
</para></entry>
</row>
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 5c8ccb8b3b..7bad94f908 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -49,7 +49,7 @@ CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
@@ -68,7 +68,7 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colliculocale);
+ Assert((collcollate && collctype) || colllocale);
/*
* Make sure there is no existing collation of same name & encoding.
@@ -191,10 +191,10 @@ CollationCreate(const char *collname, Oid collnamespace,
values[Anum_pg_collation_collctype - 1] = CStringGetTextDatum(collctype);
else
nulls[Anum_pg_collation_collctype - 1] = true;
- if (colliculocale)
- values[Anum_pg_collation_colliculocale - 1] = CStringGetTextDatum(colliculocale);
+ if (colllocale)
+ values[Anum_pg_collation_colllocale - 1] = CStringGetTextDatum(colllocale);
else
- nulls[Anum_pg_collation_colliculocale - 1] = true;
+ nulls[Anum_pg_collation_colllocale - 1] = true;
if (collicurules)
values[Anum_pg_collation_collicurules - 1] = CStringGetTextDatum(collicurules);
else
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 58c059fdb7..27564e569a 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -68,7 +68,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colliculocale;
+ char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -159,11 +159,11 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
else
collctype = NULL;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colliculocale, &isnull);
+ datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colllocale, &isnull);
if (!isnull)
- colliculocale = TextDatumGetCString(datum);
+ colllocale = TextDatumGetCString(datum);
else
- colliculocale = NULL;
+ colllocale = NULL;
/*
* When the ICU locale comes from an existing collation, do not
@@ -196,7 +196,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collcollate = NULL;
collctype = NULL;
- colliculocale = NULL;
+ colllocale = NULL;
collicurules = NULL;
if (providerEl)
@@ -236,7 +236,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collctype = defGetString(localeEl);
}
else
- colliculocale = defGetString(localeEl);
+ colllocale = defGetString(localeEl);
}
if (lccollateEl)
@@ -261,7 +261,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
else if (collprovider == COLLPROVIDER_ICU)
{
- if (!colliculocale)
+ if (!colllocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("parameter \"%s\" must be specified",
@@ -273,20 +273,20 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
*/
if (!IsBinaryUpgrade)
{
- char *langtag = icu_language_tag(colliculocale,
+ char *langtag = icu_language_tag(colllocale,
icu_validation_level);
- if (langtag && strcmp(colliculocale, langtag) != 0)
+ if (langtag && strcmp(colllocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, colliculocale)));
+ langtag, colllocale)));
- colliculocale = langtag;
+ colllocale = langtag;
}
}
- icu_validate_locale(colliculocale);
+ icu_validate_locale(colllocale);
}
/*
@@ -334,7 +334,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colliculocale : collcollate);
+ collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
newoid = CollationCreate(collName,
collNamespace,
@@ -344,7 +344,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collencoding,
collcollate,
collctype,
- colliculocale,
+ colllocale,
collicurules,
collversion,
if_not_exists,
@@ -435,7 +435,7 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
/* cannot change from NULL to non-NULL or vice versa */
@@ -502,7 +502,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
provider == COLLPROVIDER_ICU ?
- Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ Anum_pg_database_datlocale : Anum_pg_database_datcollate);
locale = TextDatumGetCString(datum);
@@ -523,7 +523,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
Assert(provider != COLLPROVIDER_DEFAULT);
datum = SysCacheGetAttrNotNull(COLLOID, colltp,
provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
locale = TextDatumGetCString(datum);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index b1327de71e..d1de46e759 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -118,7 +118,7 @@ static bool get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion);
@@ -675,7 +675,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
int src_encoding = -1;
char *src_collate = NULL;
char *src_ctype = NULL;
- char *src_iculocale = NULL;
+ char *src_locale = NULL;
char *src_icurules = NULL;
char src_locprovider = '\0';
char *src_collversion = NULL;
@@ -713,7 +713,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dbiculocale = NULL;
+ char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -903,7 +903,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (dctype && dctype->arg)
dbctype = defGetString(dctype);
if (diculocale && diculocale->arg)
- dbiculocale = defGetString(diculocale);
+ dblocale = defGetString(diculocale);
if (dicurules && dicurules->arg)
dbicurules = defGetString(dicurules);
if (dlocprovider && dlocprovider->arg)
@@ -971,7 +971,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
&src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_allowconn, &src_hasloginevt,
&src_frozenxid, &src_minmxid, &src_deftablespace,
- &src_collate, &src_ctype, &src_iculocale, &src_icurules, &src_locprovider,
+ &src_collate, &src_ctype, &src_locale, &src_icurules, &src_locprovider,
&src_collversion))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
@@ -1027,12 +1027,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dbiculocale == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
{
if (dlocale && dlocale->arg)
- dbiculocale = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
else
- dbiculocale = src_iculocale;
+ dblocale = src_locale;
}
if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
dbicurules = src_icurules;
@@ -1071,7 +1071,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* This would happen if template0 uses the libc provider but the new
* database uses icu.
*/
- if (!dbiculocale)
+ if (!dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALE or ICU_LOCALE must be specified")));
@@ -1081,26 +1081,26 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* database, preserve locale string. Otherwise, canonicalize to a
* language tag.
*/
- if (!IsBinaryUpgrade && dbiculocale != src_iculocale)
+ if (!IsBinaryUpgrade && dblocale != src_locale)
{
- char *langtag = icu_language_tag(dbiculocale,
+ char *langtag = icu_language_tag(dblocale,
icu_validation_level);
- if (langtag && strcmp(dbiculocale, langtag) != 0)
+ if (langtag && strcmp(dblocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, dbiculocale)));
+ langtag, dblocale)));
- dbiculocale = langtag;
+ dblocale = langtag;
}
}
- icu_validate_locale(dbiculocale);
+ icu_validate_locale(dblocale);
}
else
{
- if (dbiculocale)
+ if (dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1157,13 +1157,13 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
char *val1;
char *val2;
- Assert(dbiculocale);
- Assert(src_iculocale);
- if (strcmp(dbiculocale, src_iculocale) != 0)
+ Assert(dblocale);
+ Assert(src_locale);
+ if (strcmp(dblocale, src_locale) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("new ICU locale (%s) is incompatible with the ICU locale of the template database (%s)",
- dbiculocale, src_iculocale),
+ dblocale, src_locale),
errhint("Use the same ICU locale as in the template database, or use template0 as template.")));
val1 = dbicurules;
@@ -1197,7 +1197,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *actual_versionstr;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1225,7 +1225,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1364,8 +1364,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dbiculocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dbiculocale));
+ Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
+ (dblocprovider != COLLPROVIDER_ICU && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -1383,10 +1383,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);
new_record[Anum_pg_database_datcollate - 1] = CStringGetTextDatum(dbcollate);
new_record[Anum_pg_database_datctype - 1] = CStringGetTextDatum(dbctype);
- if (dbiculocale)
- new_record[Anum_pg_database_daticulocale - 1] = CStringGetTextDatum(dbiculocale);
+ if (dblocale)
+ new_record[Anum_pg_database_datlocale - 1] = CStringGetTextDatum(dblocale);
else
- new_record_nulls[Anum_pg_database_daticulocale - 1] = true;
+ new_record_nulls[Anum_pg_database_datlocale - 1] = true;
if (dbicurules)
new_record[Anum_pg_database_daticurules - 1] = CStringGetTextDatum(dbicurules);
else
@@ -2472,7 +2472,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
if (isnull)
elog(ERROR, "unexpected null in pg_database");
newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
@@ -2670,7 +2670,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
ReleaseSysCache(tp);
@@ -2697,7 +2697,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion)
@@ -2808,13 +2808,13 @@ get_db_info(const char *name, LOCKMODE lockmode,
datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datctype);
*dbCtype = TextDatumGetCString(datum);
}
- if (dbIculocale)
+ if (dbLocale)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_daticulocale, &isnull);
+ datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datlocale, &isnull);
if (isnull)
- *dbIculocale = NULL;
+ *dbLocale = NULL;
else
- *dbIculocale = TextDatumGetCString(datum);
+ *dbLocale = TextDatumGetCString(datum);
}
if (dbIcurules)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 79b59b0af7..45fe847320 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1606,7 +1606,7 @@ pg_newlocale_from_collation(Oid collid)
const char *iculocstr;
const char *icurules;
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colliculocale);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
iculocstr = TextDatumGetCString(datum);
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
@@ -1627,7 +1627,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
TextDatumGetCString(datum));
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5ffe9bdd98..154912ecb4 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -320,7 +320,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
bool isnull;
char *collate;
char *ctype;
- char *iculocale;
+ char *datlocale;
/* Fetch our pg_database row normally, via syscache */
tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
@@ -429,8 +429,8 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *icurules;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_daticulocale);
- iculocale = TextDatumGetCString(datum);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
if (!isnull)
@@ -438,10 +438,10 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
else
icurules = NULL;
- make_icu_collator(iculocale, icurules, &default_locale);
+ make_icu_collator(datlocale, icurules, &default_locale);
}
else
- iculocale = NULL;
+ datlocale = NULL;
default_locale.provider = dbform->datlocprovider;
@@ -466,7 +466,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? iculocale : collate);
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ac409b0006..90f793632a 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -145,7 +145,7 @@ static char *lc_numeric = NULL;
static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
-static char *icu_locale = NULL;
+static char *datlocale = NULL;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -1515,8 +1515,8 @@ bootstrap_template1(void)
bki_lines = replace_token(bki_lines, "LC_CTYPE",
escape_quotes_bki(lc_ctype));
- bki_lines = replace_token(bki_lines, "ICU_LOCALE",
- icu_locale ? escape_quotes_bki(icu_locale) : "_null_");
+ bki_lines = replace_token(bki_lines, "DATLOCALE",
+ datlocale ? escape_quotes_bki(datlocale) : "_null_");
bki_lines = replace_token(bki_lines, "ICU_RULES",
icu_rules ? escape_quotes_bki(icu_rules) : "_null_");
@@ -2363,8 +2363,8 @@ setlocales(void)
lc_monetary = locale;
if (!lc_messages)
lc_messages = locale;
- if (!icu_locale && locale_provider == COLLPROVIDER_ICU)
- icu_locale = locale;
+ if (!datlocale && locale_provider != COLLPROVIDER_LIBC)
+ datlocale = locale;
}
/*
@@ -2395,17 +2395,17 @@ setlocales(void)
char *langtag;
/* acquire default locale from the environment, if not specified */
- if (icu_locale == NULL)
+ if (datlocale == NULL)
pg_fatal("ICU locale must be specified");
/* canonicalize to a language tag */
- langtag = icu_language_tag(icu_locale);
+ langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
- langtag, icu_locale);
- pg_free(icu_locale);
- icu_locale = langtag;
+ langtag, datlocale);
+ pg_free(datlocale);
+ datlocale = langtag;
- icu_validate_locale(icu_locale);
+ icu_validate_locale(datlocale);
/*
* In supported builds, the ICU locale ID will be opened during
@@ -2599,14 +2599,14 @@ setup_locale_encoding(void)
strcmp(lc_ctype, lc_numeric) == 0 &&
strcmp(lc_ctype, lc_monetary) == 0 &&
strcmp(lc_ctype, lc_messages) == 0 &&
- (!icu_locale || strcmp(lc_ctype, icu_locale) == 0))
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (icu_locale)
- printf(_(" ICU locale: %s\n"), icu_locale);
+ if (datlocale)
+ printf(_(" ICU locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3277,7 +3277,7 @@ main(int argc, char *argv[])
pg_fatal("unrecognized locale provider: %s", optarg);
break;
case 16:
- icu_locale = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
break;
case 17:
icu_rules = pg_strdup(optarg);
@@ -3312,7 +3312,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (icu_locale && locale_provider != COLLPROVIDER_ICU)
+ if (datlocale && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 2225a12718..a67b4b8225 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2984,7 +2984,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider,
i_collate,
i_ctype,
- i_daticulocale,
+ i_datlocale,
i_daticurules,
i_frozenxid,
i_minmxid,
@@ -3003,7 +3003,7 @@ dumpDatabase(Archive *fout)
*datlocprovider,
*collate,
*ctype,
- *iculocale,
+ *locale,
*icurules,
*datistemplate,
*datconnlimit,
@@ -3027,10 +3027,12 @@ dumpDatabase(Archive *fout)
appendPQExpBufferStr(dbQry, "datminmxid, ");
else
appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
- if (fout->remoteVersion >= 150000)
- appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale, datcollversion, ");
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
+ else if (fout->remoteVersion >= 150000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
else
- appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS daticulocale, NULL AS datcollversion, ");
+ appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(dbQry, "daticurules, ");
else
@@ -3051,7 +3053,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider = PQfnumber(res, "datlocprovider");
i_collate = PQfnumber(res, "datcollate");
i_ctype = PQfnumber(res, "datctype");
- i_daticulocale = PQfnumber(res, "daticulocale");
+ i_datlocale = PQfnumber(res, "datlocale");
i_daticurules = PQfnumber(res, "daticurules");
i_frozenxid = PQfnumber(res, "datfrozenxid");
i_minmxid = PQfnumber(res, "datminmxid");
@@ -3070,10 +3072,10 @@ dumpDatabase(Archive *fout)
datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
collate = PQgetvalue(res, 0, i_collate);
ctype = PQgetvalue(res, 0, i_ctype);
- if (!PQgetisnull(res, 0, i_daticulocale))
- iculocale = PQgetvalue(res, 0, i_daticulocale);
+ if (!PQgetisnull(res, 0, i_datlocale))
+ locale = PQgetvalue(res, 0, i_datlocale);
else
- iculocale = NULL;
+ locale = NULL;
if (!PQgetisnull(res, 0, i_daticurules))
icurules = PQgetvalue(res, 0, i_daticurules);
else
@@ -3138,11 +3140,12 @@ dumpDatabase(Archive *fout)
appendStringLiteralAH(creaQry, ctype, fout);
}
}
- if (iculocale)
+ if (locale)
{
appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
- appendStringLiteralAH(creaQry, iculocale, fout);
+ appendStringLiteralAH(creaQry, locale, fout);
}
+
if (icurules)
{
appendPQExpBufferStr(creaQry, " ICU_RULES = ");
@@ -13756,12 +13759,12 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
int i_collisdeterministic;
int i_collcollate;
int i_collctype;
- int i_colliculocale;
+ int i_colllocale;
int i_collicurules;
const char *collprovider;
const char *collcollate;
const char *collctype;
- const char *colliculocale;
+ const char *colllocale;
const char *collicurules;
/* Do nothing in data-only dump */
@@ -13793,12 +13796,15 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
appendPQExpBufferStr(query,
"true AS collisdeterministic, ");
- if (fout->remoteVersion >= 150000)
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(query,
+ "colllocale, ");
+ else if (fout->remoteVersion >= 150000)
appendPQExpBufferStr(query,
- "colliculocale, ");
+ "colliculocale AS colllocale, ");
else
appendPQExpBufferStr(query,
- "NULL AS colliculocale, ");
+ "NULL AS colllocale, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(query,
@@ -13820,7 +13826,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
i_collisdeterministic = PQfnumber(res, "collisdeterministic");
i_collcollate = PQfnumber(res, "collcollate");
i_collctype = PQfnumber(res, "collctype");
- i_colliculocale = PQfnumber(res, "colliculocale");
+ i_colllocale = PQfnumber(res, "colllocale");
i_collicurules = PQfnumber(res, "collicurules");
collprovider = PQgetvalue(res, 0, i_collprovider);
@@ -13847,10 +13853,10 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
collctype = NULL;
}
- if (!PQgetisnull(res, 0, i_colliculocale))
- colliculocale = PQgetvalue(res, 0, i_colliculocale);
+ if (!PQgetisnull(res, 0, i_colllocale))
+ colllocale = PQgetvalue(res, 0, i_colllocale);
else
- colliculocale = NULL;
+ colllocale = NULL;
if (!PQgetisnull(res, 0, i_collicurules))
collicurules = PQgetvalue(res, 0, i_collicurules);
@@ -13880,7 +13886,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
if (collprovider[0] == 'd')
{
- if (collcollate || collctype || colliculocale || collicurules)
+ if (collcollate || collctype || colllocale || collicurules)
pg_log_warning("invalid collation \"%s\"", qcollname);
/* no locale -- the default collation cannot be reloaded anyway */
@@ -13889,16 +13895,16 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
{
if (fout->remoteVersion >= 150000)
{
- if (collcollate || collctype || !colliculocale)
+ if (collcollate || collctype || !colllocale)
pg_log_warning("invalid collation \"%s\"", qcollname);
appendPQExpBufferStr(q, ", locale = ");
- appendStringLiteralAH(q, colliculocale ? colliculocale : "",
+ appendStringLiteralAH(q, colllocale ? colllocale : "",
fout);
}
else
{
- if (!collcollate || !collctype || colliculocale ||
+ if (!collcollate || !collctype || colllocale ||
strcmp(collcollate, collctype) != 0)
pg_log_warning("invalid collation \"%s\"", qcollname);
@@ -13914,7 +13920,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
}
else if (collprovider[0] == 'c')
{
- if (colliculocale || collicurules || !collcollate || !collctype)
+ if (colllocale || collicurules || !collcollate || !collctype)
pg_log_warning("invalid collation \"%s\"", qcollname);
if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c
index 183c2f84eb..101fe855fc 100644
--- a/src/bin/pg_upgrade/info.c
+++ b/src/bin/pg_upgrade/info.c
@@ -328,18 +328,24 @@ get_template0_info(ClusterInfo *cluster)
int i_datlocprovider;
int i_datcollate;
int i_datctype;
- int i_daticulocale;
+ int i_datlocale;
- if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
dbres = executeQueryOrDie(conn,
"SELECT encoding, datlocprovider, "
- " datcollate, datctype, daticulocale "
+ " datcollate, datctype, datlocale "
+ "FROM pg_catalog.pg_database "
+ "WHERE datname='template0'");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ dbres = executeQueryOrDie(conn,
+ "SELECT encoding, datlocprovider, "
+ " datcollate, datctype, daticulocale AS datlocale"
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
else
dbres = executeQueryOrDie(conn,
"SELECT encoding, 'c' AS datlocprovider, "
- " datcollate, datctype, NULL AS daticulocale "
+ " datcollate, datctype, NULL AS datlocale "
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
@@ -353,16 +359,16 @@ get_template0_info(ClusterInfo *cluster)
i_datlocprovider = PQfnumber(dbres, "datlocprovider");
i_datcollate = PQfnumber(dbres, "datcollate");
i_datctype = PQfnumber(dbres, "datctype");
- i_daticulocale = PQfnumber(dbres, "daticulocale");
+ i_datlocale = PQfnumber(dbres, "datlocale");
locale->db_encoding = atoi(PQgetvalue(dbres, 0, i_datencoding));
locale->db_collprovider = PQgetvalue(dbres, 0, i_datlocprovider)[0];
locale->db_collate = pg_strdup(PQgetvalue(dbres, 0, i_datcollate));
locale->db_ctype = pg_strdup(PQgetvalue(dbres, 0, i_datctype));
- if (PQgetisnull(dbres, 0, i_daticulocale))
- locale->db_iculocale = NULL;
+ if (PQgetisnull(dbres, 0, i_datlocale))
+ locale->db_locale = NULL;
else
- locale->db_iculocale = pg_strdup(PQgetvalue(dbres, 0, i_daticulocale));
+ locale->db_locale = pg_strdup(PQgetvalue(dbres, 0, i_datlocale));
cluster->template0 = locale;
@@ -392,12 +398,15 @@ get_db_infos(ClusterInfo *cluster)
snprintf(query, sizeof(query),
"SELECT d.oid, d.datname, d.encoding, d.datcollate, d.datctype, ");
- if (GET_MAJOR_VERSION(cluster->major_version) < 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
+ snprintf(query + strlen(query), sizeof(query) - strlen(query),
+ "datlocprovider, datlocale, ");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "'c' AS datlocprovider, NULL AS daticulocale, ");
+ "datlocprovider, daticulocale AS datlocale, ");
else
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "datlocprovider, daticulocale, ");
+ "'c' AS datlocprovider, NULL AS datlocale, ");
snprintf(query + strlen(query), sizeof(query) - strlen(query),
"pg_catalog.pg_tablespace_location(t.oid) AS spclocation "
"FROM pg_catalog.pg_database d "
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 10c94a6c1f..bb261353bd 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -391,7 +391,7 @@ setup(char *argv0, bool *live_check)
* Copy locale and encoding information into the new cluster's template0.
*
* We need to copy the encoding, datlocprovider, datcollate, datctype, and
- * daticulocale. We don't need datcollversion because that's never set for
+ * datlocale. We don't need datcollversion because that's never set for
* template0.
*/
static void
@@ -400,7 +400,7 @@ set_locale_and_encoding(void)
PGconn *conn_new_template1;
char *datcollate_literal;
char *datctype_literal;
- char *daticulocale_literal = NULL;
+ char *datlocale_literal = NULL;
DbLocaleInfo *locale = old_cluster.template0;
prep_status("Setting locale and encoding for new cluster");
@@ -414,15 +414,29 @@ set_locale_and_encoding(void)
datctype_literal = PQescapeLiteral(conn_new_template1,
locale->db_ctype,
strlen(locale->db_ctype));
- if (locale->db_iculocale)
- daticulocale_literal = PQescapeLiteral(conn_new_template1,
- locale->db_iculocale,
- strlen(locale->db_iculocale));
+ if (locale->db_locale)
+ datlocale_literal = PQescapeLiteral(conn_new_template1,
+ locale->db_locale,
+ strlen(locale->db_locale));
else
- daticulocale_literal = pg_strdup("NULL");
+ datlocale_literal = pg_strdup("NULL");
/* update template0 in new cluster */
- if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
+ if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1700)
+ PQclear(executeQueryOrDie(conn_new_template1,
+ "UPDATE pg_catalog.pg_database "
+ " SET encoding = %d, "
+ " datlocprovider = '%c', "
+ " datcollate = %s, "
+ " datctype = %s, "
+ " datlocale = %s "
+ " WHERE datname = 'template0' ",
+ locale->db_encoding,
+ locale->db_collprovider,
+ datcollate_literal,
+ datctype_literal,
+ datlocale_literal));
+ else if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
" SET encoding = %d, "
@@ -435,7 +449,7 @@ set_locale_and_encoding(void)
locale->db_collprovider,
datcollate_literal,
datctype_literal,
- daticulocale_literal));
+ datlocale_literal));
else
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
@@ -449,7 +463,7 @@ set_locale_and_encoding(void)
PQfreemem(datcollate_literal);
PQfreemem(datctype_literal);
- PQfreemem(daticulocale_literal);
+ PQfreemem(datlocale_literal);
PQfinish(conn_new_template1);
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index d9a848cbfd..70ac424bc9 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -208,7 +208,7 @@ typedef struct
char *db_collate;
char *db_ctype;
char db_collprovider;
- char *db_iculocale;
+ char *db_locale;
int db_encoding;
} DbLocaleInfo;
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index d951ed3af0..41d06d272b 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -104,6 +104,8 @@ if ($oldnode->pg_version >= 11)
push @custom_opts, '--allow-group-access';
}
+my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
+
# Set up the locale settings for the original cluster, so that we
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
@@ -111,15 +113,22 @@ if ($oldnode->pg_version >= 11)
my $original_encoding = "6"; # UTF-8
my $original_provider = "c";
my $original_locale = "C";
-my $original_iculocale = "";
+my $original_datlocale = "";
my $provider_field = "'c' AS datlocprovider";
-my $iculocale_field = "NULL AS daticulocale";
-if ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
+my $datlocale_field = "NULL AS datlocale";
+if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$provider_field = "datlocprovider";
- $iculocale_field = "daticulocale";
+ if ($oldversion >= 17)
+ {
+ $datlocale_field = "datlocale";
+ }
+ else
+ {
+ $datlocale_field = "daticulocale AS datlocale";
+ }
$original_provider = "i";
- $original_iculocale = "fr-CA";
+ $original_datlocale = "fr-CA";
}
my @initdb_params = @custom_opts;
@@ -139,10 +148,10 @@ $oldnode->start;
my $result;
$result = $oldnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -422,10 +431,10 @@ if (-d $log_path)
# Test that upgraded cluster has original locale settings.
$result = $newnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index b6a4eb1d56..b943569050 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -937,14 +937,18 @@ listAllDbs(const char *pattern, bool verbose)
" d.datctype as \"%s\",\n",
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " d.datlocale as \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" d.daticulocale as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" NULL as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
" d.daticurules as \"%s\",\n",
@@ -4983,14 +4987,18 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " c.colllocale AS \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" c.colliculocale AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" c.collcollate AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 10c363d2ee..7396ff10c4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -29,6 +29,6 @@
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
- colliculocale => 'und' },
+ colllocale => 'und' },
]
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 5f08eb0a4a..a3e196fb53 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -42,7 +42,7 @@ CATALOG(pg_collation,3456,CollationRelationId)
#ifdef CATALOG_VARLEN /* variable-length fields start here */
text collcollate BKI_DEFAULT(_null_); /* LC_COLLATE setting */
text collctype BKI_DEFAULT(_null_); /* LC_CTYPE setting */
- text colliculocale BKI_DEFAULT(_null_); /* ICU locale ID */
+ text colllocale BKI_DEFAULT(_null_); /* locale ID */
text collicurules BKI_DEFAULT(_null_); /* ICU collation rules */
text collversion BKI_DEFAULT(_null_); /* provider-dependent
* version of collation
@@ -94,7 +94,7 @@ extern Oid CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
diff --git a/src/include/catalog/pg_database.dat b/src/include/catalog/pg_database.dat
index 4306e8a3e8..c2ba636f8d 100644
--- a/src/include/catalog/pg_database.dat
+++ b/src/include/catalog/pg_database.dat
@@ -18,7 +18,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE',
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE',
daticurules => 'ICU_RULES', datacl => '_null_' },
]
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 014baa7bab..dbd4379ffa 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -75,7 +75,7 @@ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID
text datctype BKI_FORCE_NOT_NULL;
/* ICU locale ID */
- text daticulocale;
+ text datlocale;
/* ICU collation rules */
text daticurules;
diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out
index 7a05c75967..8ca93f4dea 100644
--- a/src/test/regress/expected/collate.icu.utf8.out
+++ b/src/test/regress/expected/collate.icu.utf8.out
@@ -1024,7 +1024,7 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
@@ -1032,7 +1032,7 @@ ERROR: collation "test0" already exists
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
RESET icu_validation_level;
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index ad02772562..69060fe3c0 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -6221,9 +6221,9 @@ List of schemas
(0 rows)
\dO "no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.access.privilege"
@@ -6410,9 +6410,9 @@ cross-database references are not implemented: "no.such.schema"."no.such.languag
(0 rows)
\dO "no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.schema"."no.such.access.privilege"
@@ -6553,9 +6553,9 @@ List of text search templates
(0 rows)
\dO regression."no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp regression."no.such.schema"."no.such.access.privilege"
diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql
index 3db9e25913..03837de846 100644
--- a/src/test/regress/sql/collate.icu.utf8.sql
+++ b/src/test/regress/sql/collate.icu.utf8.sql
@@ -363,14 +363,14 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
--
2.34.1
[text/x-patch] v18-0005-Introduce-collation-provider-builtin.patch (85.7K, ../../[email protected]/6-v18-0005-Introduce-collation-provider-builtin.patch)
download | inline diff:
From e4d89d0e976283e72b33a48d6a6b7fb5d8fceeca Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 1 May 2023 15:38:29 -0700
Subject: [PATCH v18 5/6] Introduce collation provider "builtin".
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Three locales are offered by the builtin provider: C, C.UTF-8, and
UCS_BASIC.
The builtin "C" locale is equal in semantics and implementation to
the libc "C" locale (neither of which actually use libc).
The builtin "C.UTF-8" locale offers similar semantics to the libc
"C.UTF-8" locale, which is collation according to code point combined
with simple Unicode character semantics. Unlike the libc "C.UTF-8"
locale, the builtin "C.UTF-8" is available on all platforms with
consistent behavior, and benefits from additional optimizations.
The builtin "UCS_BASIC" locale offers collation according to code
point order and more complete Unicode character semantics. As the SQL
standard requires, it offers full case mappings that may increase the
length of a string, such as "ß" changing to "SS" when uppercased.
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 88 ++++--
doc/src/sgml/ref/create_collation.sgml | 11 +-
doc/src/sgml/ref/create_database.sgml | 8 +-
doc/src/sgml/ref/createdb.sgml | 2 +-
doc/src/sgml/ref/initdb.sgml | 17 +-
src/backend/catalog/pg_collation.c | 5 +-
src/backend/commands/collationcmds.c | 93 ++++--
src/backend/commands/dbcommands.c | 121 ++++++--
src/backend/regex/regc_pg_locale.c | 41 ++-
src/backend/utils/adt/formatting.c | 133 +++++++++
src/backend/utils/adt/pg_locale.c | 162 +++++++++--
src/backend/utils/init/postinit.c | 46 ++-
src/bin/initdb/initdb.c | 58 ++--
src/bin/initdb/t/001_initdb.pl | 57 +++-
src/bin/pg_dump/pg_dump.c | 49 ++--
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 70 +++--
src/bin/psql/describe.c | 4 +-
src/bin/scripts/createdb.c | 18 +-
src/bin/scripts/t/020_createdb.pl | 78 +++++
src/include/catalog/pg_collation.dat | 6 +-
src/include/catalog/pg_collation.h | 3 +
src/include/utils/pg_locale.h | 9 +-
src/test/icu/t/010_database.pl | 22 +-
src/test/regress/expected/collate.out | 24 +-
src/test/regress/expected/collate.utf8.out | 287 +++++++++++++++++++
src/test/regress/expected/collate.utf8_1.out | 8 +
src/test/regress/parallel_schedule | 4 +-
src/test/regress/sql/collate.sql | 10 +
src/test/regress/sql/collate.utf8.sql | 122 ++++++++
29 files changed, 1393 insertions(+), 163 deletions(-)
create mode 100644 src/test/regress/expected/collate.utf8.out
create mode 100644 src/test/regress/expected/collate.utf8_1.out
create mode 100644 src/test/regress/sql/collate.utf8.sql
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 4422b0cc92..2abd898115 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -342,22 +342,14 @@ initdb --locale=sv_SE
<title>Locale Providers</title>
<para>
- <productname>PostgreSQL</productname> supports multiple <firstterm>locale
- providers</firstterm>. This specifies which library supplies the locale
- data. One standard provider name is <literal>libc</literal>, which uses
- the locales provided by the operating system C library. These are the
- locales used by most tools provided by the operating system. Another
- provider is <literal>icu</literal>, which uses the external
- ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can
- only be used if support for ICU was configured when PostgreSQL was built.
+ A locale provider specifies which library defines the locale behavior for
+ collations and character classifications.
</para>
<para>
The commands and tools that select the locale settings, as described
- above, each have an option to select the locale provider. The examples
- shown earlier all use the <literal>libc</literal> provider, which is the
- default. Here is an example to initialize a database cluster using the
- ICU provider:
+ above, each have an option to select the locale provider. Here is an
+ example to initialize a database cluster using the ICU provider:
<programlisting>
initdb --locale-provider=icu --icu-locale=en
</programlisting>
@@ -370,12 +362,74 @@ initdb --locale-provider=icu --icu-locale=en
</para>
<para>
- Which locale provider to use depends on individual requirements. For most
- basic uses, either provider will give adequate results. For the libc
- provider, it depends on what the operating system offers; some operating
- systems are better than others. For advanced uses, ICU offers more locale
- variants and customization options.
+ Regardless of the locale provider, the operating system is still used to
+ provide some locale-aware behavior, such as messages (see <xref
+ linkend="guc-lc-messages"/>).
</para>
+
+ <para>
+ The available locale providers are listed below.
+ </para>
+
+ <sect3 id="locale-provider-builtin">
+ <title>Builtin</title>
+ <para>
+ The <literal>builtin</literal> provider uses built-in operations. Only
+ the <literal>C</literal> and <literal>C.UTF-8</literal> locales are
+ supported for this provider.
+ </para>
+ <para>
+ The <literal>C</literal> locale behavior is identical to the
+ <literal>C</literal> locale in the libc provider. When using this locale,
+ the behavior may depend on the database encoding.
+ </para>
+ <para>
+ The <literal>C.UTF-8</literal> locale is available only for when the
+ database encoding is <literal>UTF-8</literal>, and the behavior is based
+ on Unicode. The collation uses the code point values only. The regular
+ expression character classes are based on the "POSIX Compatible"
+ semantics, and the case mapping is the "simple" variant.
+ </para>
+ </sect3>
+ <sect3 id="locale-provider-icu">
+ <title>ICU</title>
+ <para>
+ The <literal>icu</literal> provider uses the external
+ ICU<indexterm><primary>ICU</primary></indexterm>
+ library. <productname>PostgreSQL</productname> must have been configured
+ with support.
+ </para>
+ <para>
+ ICU provides collation and character classification behavior that is
+ independent of the operating system and database encoding, which is
+ preferable if you expect to transition to other platforms without any
+ change in results. <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal> can be set independently of the ICU locale.
+ </para>
+ <note>
+ <para>
+ For the ICU provider, results may depend on the version of the ICU
+ library used, as it is updated to reflect changes in natural language
+ over time.
+ </para>
+ </note>
+ </sect3>
+ <sect3 id="locale-provider-libc">
+ <title>libc</title>
+ <para>
+ The <literal>libc</literal> provider uses the operating system's C
+ library. The collation and character classification behavior is
+ controlled by the settings <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal>, so they cannot be set independently.
+ </para>
+ <note>
+ <para>
+ The same locale name may have different behavior on different platforms
+ when using the libc provider.
+ </para>
+ </note>
+ </sect3>
+
</sect2>
<sect2 id="icu-locales">
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 5cf9777764..85f18cbbe5 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -96,6 +96,11 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<replaceable>locale</replaceable>, you cannot specify either of those
parameters.
</para>
+ <para>
+ If <replaceable>provider</replaceable> is <literal>builtin</literal>,
+ then <replaceable>locale</replaceable> must be specified and set to
+ either <literal>C</literal> or <literal>C.UTF-8</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -129,9 +134,9 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<listitem>
<para>
Specifies the provider to use for locale services associated with this
- collation. Possible values are
- <literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
- (if the server was built with ICU support) or <literal>libc</literal>.
+ collation. Possible values are <literal>builtin</literal>,
+ <literal>icu</literal><indexterm><primary>ICU</primary></indexterm> (if
+ the server was built with ICU support) or <literal>libc</literal>.
<literal>libc</literal> is the default. See <xref
linkend="locale-providers"/> for details.
</para>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 72927960eb..1f5cdf1271 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -162,6 +162,12 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
linkend="create-database-lc-ctype"/>, or <xref
linkend="create-database-icu-locale"/> individually.
</para>
+ <para>
+ If <xref linkend="create-database-locale-provider"/> is
+ <literal>builtin</literal>, then <replaceable>locale</replaceable>
+ must be specified and set to either <literal>C</literal> or
+ <literal>C.UTF-8</literal>.
+ </para>
<tip>
<para>
The other locale settings <xref linkend="guc-lc-messages"/>, <xref
@@ -243,7 +249,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<listitem>
<para>
Specifies the provider to use for the default collation in this
- database. Possible values are
+ database. Possible values are <literal>builtin</literal>,
<literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
(if the server was built with ICU support) or <literal>libc</literal>.
By default, the provider is the same as that of the <xref
diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml
index e4647d5ce7..d3e815f659 100644
--- a/doc/src/sgml/ref/createdb.sgml
+++ b/doc/src/sgml/ref/createdb.sgml
@@ -171,7 +171,7 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
Specifies the locale provider for the database's default collation.
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index cd75cae10e..08a1c2538f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -286,6 +286,11 @@ PostgreSQL documentation
environment that <command>initdb</command> runs in. Locale
support is described in <xref linkend="locale"/>.
</para>
+ <para>
+ If <option>--locale-provider</option> is <literal>builtin</literal>,
+ <option>--locale</option> must be specified and set to
+ <literal>C</literal> or <literal>C.UTF-8</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -314,8 +319,18 @@ PostgreSQL documentation
</listitem>
</varlistentry>
+ <varlistentry id="app-initdb-builtin-locale">
+ <term><option>--builtin-locale=<replaceable>locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the locale name when the builtin provider is used. Locale support
+ is described in <xref linkend="locale"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-initdb-option-locale-provider">
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
This option sets the locale provider for databases created in the new
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 7bad94f908..01e91000af 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -68,7 +68,10 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colllocale);
+ Assert((collprovider == COLLPROVIDER_LIBC &&
+ collcollate && collctype && !colllocale) ||
+ (collprovider != COLLPROVIDER_LIBC &&
+ !collcollate && !collctype && colllocale));
/*
* Make sure there is no existing collation of same name & encoding.
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 27564e569a..0fa073496e 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -68,7 +68,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colllocale;
+ const char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -215,7 +215,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (collproviderstr)
{
- if (pg_strcasecmp(collproviderstr, "icu") == 0)
+ if (pg_strcasecmp(collproviderstr, "builtin") == 0)
+ collprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(collproviderstr, "icu") == 0)
collprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(collproviderstr, "libc") == 0)
collprovider = COLLPROVIDER_LIBC;
@@ -245,7 +247,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (lcctypeEl)
collctype = defGetString(lcctypeEl);
- if (collprovider == COLLPROVIDER_LIBC)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ if (!colllocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("parameter \"locale\" must be specified")));
+
+ colllocale = builtin_validate_locale(GetDatabaseEncoding(),
+ colllocale);
+ }
+ else if (collprovider == COLLPROVIDER_LIBC)
{
if (!collcollate)
ereport(ERROR,
@@ -305,7 +317,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
- if (collprovider == COLLPROVIDER_ICU)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * Behavior may be different in different encodings, so set
+ * collencoding to the current database encoding. No validation is
+ * required, because the "builtin" provider is compatible with any
+ * encoding.
+ */
+ collencoding = GetDatabaseEncoding();
+ }
+ else if (collprovider == COLLPROVIDER_ICU)
{
#ifdef USE_ICU
/*
@@ -334,7 +356,18 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
+ {
+ const char *locale;
+
+ if (collprovider == COLLPROVIDER_ICU)
+ locale = colllocale;
+ else if (collprovider == COLLPROVIDER_LIBC)
+ locale = collcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ collversion = get_collation_actual_version(collprovider, locale);
+ }
newoid = CollationCreate(collName,
collNamespace,
@@ -409,6 +442,7 @@ AlterCollation(AlterCollationStmt *stmt)
Form_pg_collation collForm;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
ObjectAddress address;
@@ -435,8 +469,20 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
+ if (collForm->collprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (collForm->collprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(collForm->collprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -500,11 +546,18 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_datlocale : Anum_pg_database_datcollate);
-
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(dbtup);
}
@@ -521,11 +574,19 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttrNotNull(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(colltp);
}
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index d1de46e759..d7a21adc5c 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -698,6 +698,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
DefElem *dtemplate = NULL;
DefElem *dencoding = NULL;
DefElem *dlocale = NULL;
+ DefElem *dbuiltinlocale = NULL;
DefElem *dcollate = NULL;
DefElem *dctype = NULL;
DefElem *diculocale = NULL;
@@ -713,7 +714,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dblocale = NULL;
+ const char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -762,6 +763,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errorConflictingDefElem(defel, pstate);
dlocale = defel;
}
+ else if (strcmp(defel->defname, "builtin_locale") == 0)
+ {
+ if (dbuiltinlocale)
+ errorConflictingDefElem(defel, pstate);
+ dbuiltinlocale = defel;
+ }
else if (strcmp(defel->defname, "lc_collate") == 0)
{
if (dcollate)
@@ -897,7 +904,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
dbcollate = defGetString(dlocale);
dbctype = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
}
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ dblocale = defGetString(dbuiltinlocale);
if (dcollate && dcollate->arg)
dbcollate = defGetString(dcollate);
if (dctype && dctype->arg)
@@ -910,7 +920,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *locproviderstr = defGetString(dlocprovider);
- if (pg_strcasecmp(locproviderstr, "icu") == 0)
+ if (pg_strcasecmp(locproviderstr, "builtin") == 0)
+ dblocprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(locproviderstr, "icu") == 0)
dblocprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(locproviderstr, "libc") == 0)
dblocprovider = COLLPROVIDER_LIBC;
@@ -1027,14 +1039,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
- {
- if (dlocale && dlocale->arg)
- dblocale = defGetString(dlocale);
- else
- dblocale = src_locale;
- }
- if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL)
+ dblocale = src_locale;
+ if (dbicurules == NULL)
dbicurules = src_icurules;
/* Some encodings are client only */
@@ -1059,6 +1066,27 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
check_encoding_locale_matches(encoding, dbcollate, dbctype);
+ if (dblocprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * This would happen if template0 uses the libc provider but the new
+ * database uses builtin.
+ */
+ if (!dblocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("LOCALE must be specified for the builtin provider")));
+
+ dblocale = builtin_validate_locale(encoding, dblocale);
+ }
+ else
+ {
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("BUILTIN_LOCALE cannot be specified unless locale provider is builtin")));
+ }
+
if (dblocprovider == COLLPROVIDER_ICU)
{
if (!(is_encoding_supported_by_icu(encoding)))
@@ -1100,7 +1128,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
}
else
{
- if (dblocale)
+ if (diculocale && diculocale->arg)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1111,6 +1139,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
}
+ /* for libc, locale comes from datcollate and datctype */
+ if (dblocprovider == COLLPROVIDER_LIBC)
+ dblocale = NULL;
+
/*
* Check that the new encoding and locale settings match the source
* database. We insist on this because we simply copy the source data ---
@@ -1196,8 +1228,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (src_collversion && !dcollversion)
{
char *actual_versionstr;
+ const char *locale;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ actual_versionstr = get_collation_actual_version(dblocprovider, locale);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1225,7 +1265,18 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ {
+ const char *locale;
+
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ dbcollversion = get_collation_actual_version(dblocprovider, locale);
+ }
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1364,8 +1415,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dblocale));
+ Assert((dblocprovider != COLLPROVIDER_LIBC && dblocale) ||
+ (dblocprovider == COLLPROVIDER_LIBC && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -2446,6 +2497,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
ObjectAddress address;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
@@ -2472,10 +2524,24 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
- newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
+ if (datForm->datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datlocale, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datForm->datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(datForm->datlocprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -2660,6 +2726,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
+ char *locale;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2670,8 +2737,20 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
- version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
+ if (datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ version = get_collation_actual_version(datlocprovider, locale);
ReleaseSysCache(tp);
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 6a26388bfa..7fe7b9f6d5 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -16,6 +16,8 @@
*/
#include "catalog/pg_collation.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "utils/pg_locale.h"
/*
@@ -64,6 +66,7 @@
typedef enum
{
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
+ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
@@ -75,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -266,7 +271,15 @@ pg_set_regex_collation(Oid collation)
if (GetDatabaseEncoding() == PG_UTF8)
{
if (pg_regex_locale)
- pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ {
+ if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
+ pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = pg_regex_locale->info.builtin.properties_posix;
+ }
+ else
+ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
@@ -290,6 +303,8 @@ pg_wc_isdigit(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -322,6 +337,8 @@ pg_wc_isalpha(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALPHA));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
@@ -354,6 +371,8 @@ pg_wc_isalnum(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -395,6 +414,8 @@ pg_wc_isupper(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISUPPER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
@@ -427,6 +448,8 @@ pg_wc_islower(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISLOWER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
@@ -459,6 +482,8 @@ pg_wc_isgraph(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISGRAPH));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
@@ -491,6 +516,8 @@ pg_wc_isprint(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPRINT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
@@ -523,6 +550,8 @@ pg_wc_ispunct(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
@@ -555,6 +584,8 @@ pg_wc_isspace(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISSPACE));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
@@ -588,6 +619,8 @@ pg_wc_toupper(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_case_simple(c, CaseUpper);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -628,6 +661,8 @@ pg_wc_tolower(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_case_simple(c, CaseLower);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -792,6 +827,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
#endif
break;
+ case PG_REGEX_BUILTIN:
+ max_chr = (pg_wchar) MAX_SIMPLE_CHR;
+ break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
@@ -809,6 +847,7 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break;
default:
+ Assert(false);
max_chr = 0; /* can't get here, but keep compiler quiet */
break;
}
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 829aaa8d0e..e6cbf9e588 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -77,6 +77,8 @@
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "mb/pg_wchar.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
@@ -1680,6 +1682,35 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_convert_case(dst, dstsize, src, srclen, CaseLower,
+ mylocale->info.builtin.casemap_full);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_convert_case(dst, dstsize, src, srclen, CaseLower,
+ mylocale->info.builtin.casemap_full);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
@@ -1798,6 +1829,35 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_convert_case(dst, dstsize, src, srclen, CaseUpper,
+ mylocale->info.builtin.casemap_full);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_convert_case(dst, dstsize, src, srclen, CaseUpper,
+ mylocale->info.builtin.casemap_full);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
@@ -1917,6 +1977,79 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const unsigned char *src = (unsigned char *) buff;
+ unsigned char *dst;
+ size_t dstsize = nbytes + 1;
+ int srcoff = 0;
+ int dstoff = 0;
+ CaseKind casekind;
+
+ if (mylocale->info.builtin.titlecase)
+ casekind = CaseTitle;
+ else
+ casekind = CaseUpper;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* Output workspace cannot have more codes than input bytes */
+ dst = (unsigned char *) palloc(dstsize);
+
+ while (srcoff < nbytes)
+ {
+ pg_wchar u1 = utf8_to_unicode(src + srcoff);
+ pg_wchar u2;
+ int u1len = unicode_utf8len(u1);
+ int u2len;
+
+ if (wasalnum)
+ u2 = unicode_case_simple(u1, CaseLower);
+ else
+ u2 = unicode_case_simple(u1, casekind);
+
+ u2len = unicode_utf8len(u2);
+
+ wasalnum = pg_u_isalnum(u2, mylocale->info.builtin.properties_posix);
+
+ /*
+ * If we can't fit the necessary bytes and a terminating NUL,
+ * reallocate buffer to the maximum size we might need, and
+ * shrink it later.
+ */
+ if (dstoff + u2len + 1 > dstsize)
+ {
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ dstsize = (nbytes + 1) * sizeof(pg_wchar);
+ dst = repalloc(dst, dstsize);
+ }
+
+ unicode_to_utf8(u2, dst + dstoff);
+ srcoff += u1len;
+ dstoff += u2len;
+ }
+
+ *(dst + dstoff) = '\0';
+ dstoff++;
+
+ if (dstsize == dstoff)
+ {
+ result = (char *) dst;
+ }
+ else
+ {
+ /* shrink buffer and store result */
+ result = palloc(dstoff);
+ memcpy(result, dst, dstoff);
+ pfree(dst);
+ }
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 45fe847320..74aaf82566 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1269,7 +1269,19 @@ lookup_collation_cache(Oid collation, bool set_flags)
elog(ERROR, "cache lookup failed for collation %u", collation);
collform = (Form_pg_collation) GETSTRUCT(tp);
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ Datum datum;
+ const char *colllocale;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ colllocale = TextDatumGetCString(datum);
+
+ cache_entry->collate_is_c = true;
+ cache_entry->ctype_is_c = ((strcmp(colllocale, "C") == 0) ||
+ (strcmp(colllocale, "POSIX") == 0));
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
const char *collcollate;
@@ -1320,16 +1332,30 @@ lc_collate_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_COLLATE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_COLLATE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ result = true;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1373,16 +1399,29 @@ lc_ctype_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_CTYPE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_CTYPE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ localeptr = default_locale.info.builtin.locale;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1390,6 +1429,7 @@ lc_ctype_is_c(Oid collation)
result = true;
else
result = false;
+
return (bool) result;
}
@@ -1520,10 +1560,10 @@ pg_newlocale_from_collation(Oid collid)
if (collid == DEFAULT_COLLATION_OID)
{
- if (default_locale.provider == COLLPROVIDER_ICU)
- return &default_locale;
- else
+ if (default_locale.provider == COLLPROVIDER_LIBC)
return (pg_locale_t) 0;
+ else
+ return &default_locale;
}
cache_entry = lookup_collation_cache(collid, false);
@@ -1548,7 +1588,45 @@ pg_newlocale_from_collation(Oid collid)
result.provider = collform->collprovider;
result.deterministic = collform->collisdeterministic;
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ bool casemap_full;
+ bool titlecase;
+ bool properties_posix;
+
+ const char *locstr;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ locstr = TextDatumGetCString(datum);
+
+ if (strcmp(locstr, "UCS_BASIC") == 0)
+ {
+ casemap_full = true;
+ titlecase = true;
+ properties_posix = false;
+ }
+ else if (strcmp(locstr, "C.UTF-8") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else if (strcmp(locstr, "C") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else
+ elog(ERROR, "unexpected builtin locale: %s", locstr);
+
+ result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
+ locstr);
+ result.info.builtin.casemap_full = casemap_full;
+ result.info.builtin.titlecase = titlecase;
+ result.info.builtin.properties_posix = properties_posix;
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
const char *collcollate;
const char *collctype pg_attribute_unused();
@@ -1627,6 +1705,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
+ Assert(collform->collprovider != COLLPROVIDER_BUILTIN);
datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
@@ -1678,6 +1757,14 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
+ /*
+ * The only two supported locales (C and C.UTF-8) are both based on memcmp
+ * and do not change. (The ctype behavior can change, but the versioning
+ * does not track that.)
+ */
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ return NULL;
+
#ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU)
{
@@ -2444,6 +2531,43 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
return result;
}
+const char *
+builtin_validate_locale(int encoding, const char *locale)
+{
+ const char *canonical_name = NULL;
+ int required_encoding = -1;
+
+ if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0)
+ {
+ canonical_name = "C";
+ }
+ else if (strcmp(locale, "UCS_BASIC") == 0 || strcmp(locale, "UCS_BASIC") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "UCS_BASIC";
+ }
+ else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "C.UTF-8";
+ }
+
+ if (!canonical_name)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ locale)));
+
+ if (required_encoding >= 0 && encoding != required_encoding)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("encoding \"%s\" does not match locale \"%s\"",
+ pg_encoding_to_char(encoding), locale)));
+
+ return canonical_name;
+}
+
+
#ifdef USE_ICU
/*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 154912ecb4..0cfa1ba54f 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -425,7 +425,43 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
strcmp(ctype, "POSIX") == 0)
database_ctype_is_c = true;
- if (dbform->datlocprovider == COLLPROVIDER_ICU)
+ if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
+ {
+ bool casemap_full;
+ bool titlecase;
+ bool properties_posix;
+
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
+
+ if (strcmp(datlocale, "UCS_BASIC") == 0)
+ {
+ casemap_full = true;
+ titlecase = true;
+ properties_posix = false;
+ }
+ else if (strcmp(datlocale, "C.UTF-8") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else if (strcmp(datlocale, "C") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else
+ elog(ERROR, "unexpected builtin locale: %s", datlocale);
+
+ default_locale.info.builtin.locale = MemoryContextStrdup(
+ TopMemoryContext, datlocale);
+ default_locale.info.builtin.casemap_full = casemap_full;
+ default_locale.info.builtin.titlecase = titlecase;
+ default_locale.info.builtin.properties_posix = properties_posix;
+ }
+ else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
char *icurules;
@@ -463,10 +499,16 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *actual_versionstr;
char *collversionstr;
+ char *locale;
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
+ if (dbform->datlocprovider == COLLPROVIDER_LIBC)
+ locale = collate;
+ else
+ locale = datlocale;
+
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 90f793632a..7419c38722 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -146,6 +146,7 @@ static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
static char *datlocale = NULL;
+static bool icu_locale_specified = false;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -2390,14 +2391,13 @@ setlocales(void)
lc_messages = canonname;
#endif
+ if (locale_provider != COLLPROVIDER_LIBC && datlocale == NULL)
+ pg_fatal("locale must be specified unless provider is libc");
+
if (locale_provider == COLLPROVIDER_ICU)
{
char *langtag;
- /* acquire default locale from the environment, if not specified */
- if (datlocale == NULL)
- pg_fatal("ICU locale must be specified");
-
/* canonicalize to a language tag */
langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
@@ -2442,7 +2442,8 @@ usage(const char *progname)
" set default locale in the respective category for\n"
" new databases (default taken from environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --builtin-locale=LOCALE set builtin locale name for new databases\n"));
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" set default locale provider for new databases\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
printf(_(" -T, --text-search-config=CFG\n"
@@ -2593,20 +2594,28 @@ setup_locale_encoding(void)
{
setlocales();
- if (locale_provider == COLLPROVIDER_LIBC &&
- strcmp(lc_ctype, lc_collate) == 0 &&
- strcmp(lc_ctype, lc_time) == 0 &&
- strcmp(lc_ctype, lc_numeric) == 0 &&
- strcmp(lc_ctype, lc_monetary) == 0 &&
- strcmp(lc_ctype, lc_messages) == 0 &&
- (!datlocale || strcmp(lc_ctype, datlocale) == 0))
+ if (locale_provider == COLLPROVIDER_BUILTIN &&
+ strcmp(lc_ctype, "C") == 0 &&
+ strcmp(lc_collate, "C") == 0 &&
+ strcmp(lc_time, "C") == 0 &&
+ strcmp(lc_numeric, "C") == 0 &&
+ strcmp(lc_monetary, "C") == 0 &&
+ strcmp(lc_messages, "C") == 0)
+ printf(_("The database cluster will be initialized with no locale.\n"));
+ else if (locale_provider == COLLPROVIDER_LIBC &&
+ strcmp(lc_ctype, lc_collate) == 0 &&
+ strcmp(lc_ctype, lc_time) == 0 &&
+ strcmp(lc_ctype, lc_numeric) == 0 &&
+ strcmp(lc_ctype, lc_monetary) == 0 &&
+ strcmp(lc_ctype, lc_messages) == 0 &&
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
- printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (datlocale)
- printf(_(" ICU locale: %s\n"), datlocale);
+ printf(_(" default collation provider: %s\n"), collprovider_name(locale_provider));
+ if (locale_provider != COLLPROVIDER_LIBC)
+ printf(_(" default collation locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3099,9 +3108,10 @@ main(int argc, char *argv[])
{"allow-group-access", no_argument, NULL, 'g'},
{"discard-caches", no_argument, NULL, 14},
{"locale-provider", required_argument, NULL, 15},
- {"icu-locale", required_argument, NULL, 16},
- {"icu-rules", required_argument, NULL, 17},
- {"sync-method", required_argument, NULL, 18},
+ {"builtin-locale", required_argument, NULL, 16},
+ {"icu-locale", required_argument, NULL, 17},
+ {"icu-rules", required_argument, NULL, 18},
+ {"sync-method", required_argument, NULL, 19},
{NULL, 0, NULL, 0}
};
@@ -3269,7 +3279,9 @@ main(int argc, char *argv[])
"-c debug_discard_caches=1");
break;
case 15:
- if (strcmp(optarg, "icu") == 0)
+ if (strcmp(optarg, "builtin") == 0)
+ locale_provider = COLLPROVIDER_BUILTIN;
+ else if (strcmp(optarg, "icu") == 0)
locale_provider = COLLPROVIDER_ICU;
else if (strcmp(optarg, "libc") == 0)
locale_provider = COLLPROVIDER_LIBC;
@@ -3280,9 +3292,13 @@ main(int argc, char *argv[])
datlocale = pg_strdup(optarg);
break;
case 17:
- icu_rules = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
+ icu_locale_specified = true;
break;
case 18:
+ icu_rules = pg_strdup(optarg);
+ break;
+ case 19:
if (!parse_sync_method(optarg, &sync_method))
exit(1);
break;
@@ -3312,7 +3328,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (datlocale && locale_provider != COLLPROVIDER_ICU)
+ if (icu_locale_specified && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 03376cc0f7..242f4581a5 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -117,7 +117,7 @@ if ($ENV{with_icu} eq 'yes')
{
command_fails_like(
[ 'initdb', '--no-sync', '--locale-provider=icu', "$tempdir/data2" ],
- qr/initdb: error: ICU locale must be specified/,
+ qr/initdb: error: locale must be specified unless provider is libc/,
'locale provider ICU requires --icu-locale');
command_ok(
@@ -138,7 +138,7 @@ if ($ENV{with_icu} eq 'yes')
'--lc-monetary=C', '--lc-time=C',
"$tempdir/data4"
],
- qr/^\s+ICU locale:\s+und\n/ms,
+ qr/^\s+default collation locale:\s+und\n/ms,
'options --locale-provider=icu --locale=und --lc-*=C');
command_fails_like(
@@ -184,6 +184,59 @@ else
'locale provider ICU fails since no ICU support');
}
+command_fails(
+ [ 'initdb', '--no-sync', '--locale-provider=builtin', "$tempdir/data6" ],
+ 'locale provider builtin fails without --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--locale=C',
+ "$tempdir/data7"
+ ],
+ 'locale provider builtin with --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E SQL_ASCII',
+ '--builtin-locale=C.UTF-8', "$tempdir/data9"
+ ],
+ 'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
+);
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--lc-ctype=C',
+ '--locale=C', "$tempdir/data10"
+ ],
+ 'locale provider builtin with --lc-ctype');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-locale=en',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU locale');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-rules=""',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU rules');
+
command_fails(
[ 'initdb', '--no-sync', '--locale-provider=xyz', "$tempdir/dataX" ],
'fails for invalid locale provider');
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index a67b4b8225..450c322205 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3114,7 +3114,9 @@ dumpDatabase(Archive *fout)
}
appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
- if (datlocprovider[0] == 'c')
+ if (datlocprovider[0] == 'b')
+ appendPQExpBufferStr(creaQry, "builtin");
+ else if (datlocprovider[0] == 'c')
appendPQExpBufferStr(creaQry, "libc");
else if (datlocprovider[0] == 'i')
appendPQExpBufferStr(creaQry, "icu");
@@ -3122,27 +3124,33 @@ dumpDatabase(Archive *fout)
pg_fatal("unrecognized locale provider: %s",
datlocprovider);
- if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ if (!locale && datlocprovider[0] != 'c')
+ pg_log_warning("database '%s' with provider '%s' missing datlocale",
+ datname, datlocprovider);
+
+ if (locale && datlocprovider[0] == 'c')
+ pg_log_warning("database '%s' with provider 'c' has non-NULL locale '%s'",
+ datname, locale);
+
+ /* if collate and ctype are equal, and locale is NULL, use LOCALE */
+ if (!locale && strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ locale = collate;
+
+ /* output LC_COLLATE and LC_CTYPE if different from LOCALE */
+ if (strlen(collate) > 0 && (!locale || strcmp(collate, locale) != 0))
{
- appendPQExpBufferStr(creaQry, " LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
appendStringLiteralAH(creaQry, collate, fout);
}
- else
+ if (strlen(ctype) > 0 && (!locale || strcmp(ctype, locale) != 0))
{
- if (strlen(collate) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
- appendStringLiteralAH(creaQry, collate, fout);
- }
- if (strlen(ctype) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
- appendStringLiteralAH(creaQry, ctype, fout);
- }
+ appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+ appendStringLiteralAH(creaQry, ctype, fout);
}
+
if (locale)
{
- appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LOCALE = ");
appendStringLiteralAH(creaQry, locale, fout);
}
@@ -13870,7 +13878,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
fmtQualifiedDumpable(collinfo));
appendPQExpBufferStr(q, "provider = ");
- if (collprovider[0] == 'c')
+ if (collprovider[0] == 'b')
+ appendPQExpBufferStr(q, "builtin");
+ else if (collprovider[0] == 'c')
appendPQExpBufferStr(q, "libc");
else if (collprovider[0] == 'i')
appendPQExpBufferStr(q, "icu");
@@ -13891,6 +13901,13 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
/* no locale -- the default collation cannot be reloaded anyway */
}
+ else if (collprovider[0] == 'b')
+ {
+ if (collcollate || collctype || colllocale || collicurules)
+ pg_log_warning("invalid collation \"%s\"", qcollname);
+
+ appendPQExpBufferStr(q, ", locale = 'C'");
+ }
else if (collprovider[0] == 'i')
{
if (fout->remoteVersion >= 150000)
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index 41d06d272b..94bf086ba8 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -110,13 +110,16 @@ my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
-my $original_encoding = "6"; # UTF-8
-my $original_provider = "c";
-my $original_locale = "C";
-my $original_datlocale = "";
-my $provider_field = "'c' AS datlocprovider";
-my $datlocale_field = "NULL AS datlocale";
-if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+my %encoding_number = ('UTF-8' => 6, 'SQL_ASCII' => 0);
+my $provider_field;
+my $datlocale_field;
+my $original_encoding;
+my $original_provider;
+my $original_datcollate = "C";
+my $original_datctype = "C";
+my $original_datlocale;
+
+if ($oldversion >= 15)
{
$provider_field = "datlocprovider";
if ($oldversion >= 17)
@@ -127,18 +130,52 @@ if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$datlocale_field = "daticulocale AS datlocale";
}
+}
+else
+{
+ $provider_field = "'c' AS datlocprovider";
+ $datlocale_field = "NULL AS datlocale";
+}
+
+if ($oldversion >= 17)
+{
+ $original_encoding = "UTF-8";
+ $original_provider = "b";
+ $original_datlocale = "C.UTF-8";
+}
+elsif ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+{
+ $original_encoding = "UTF-8";
$original_provider = "i";
$original_datlocale = "fr-CA";
}
+else
+{
+ my $original_encoding = "SQL_ASCII";
+ my $original_provider = "c";
+ my $original_datlocale = "";
+}
my @initdb_params = @custom_opts;
-push @initdb_params, ('--encoding', 'UTF-8');
-push @initdb_params, ('--locale', $original_locale);
-if ($original_provider eq "i")
+push @initdb_params, ('--encoding', $original_encoding);
+push @initdb_params, ('--lc-collate', $original_datcollate);
+push @initdb_params, ('--lc-ctype', $original_datctype);
+
+# add --locale-provider, if supported
+my %provider_name = ('b' => 'builtin', 'i' => 'icu', 'c' => 'libc');
+if ($oldnode->pg_version >= 15)
{
- push @initdb_params, ('--locale-provider', 'icu');
- push @initdb_params, ('--icu-locale', 'fr-CA');
+ push @initdb_params,
+ ('--locale-provider', $provider_name{$original_provider});
+ if ($original_provider eq 'b')
+ {
+ push @initdb_params, ('--builtin-locale', $original_datlocale);
+ }
+ elsif ($original_provider eq 'i')
+ {
+ push @initdb_params, ('--icu-locale', $original_datlocale);
+ }
}
$node_params{extra} = \@initdb_params;
@@ -151,7 +188,7 @@ $result = $oldnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -327,7 +364,8 @@ if (defined($ENV{oldinstall}))
}
# Create an invalid database, will be deleted below
-$oldnode->safe_psql('postgres', qq(
+$oldnode->safe_psql(
+ 'postgres', qq(
CREATE DATABASE regression_invalid;
UPDATE pg_database SET datconnlimit = -2 WHERE datname = 'regression_invalid';
));
@@ -370,7 +408,7 @@ command_checks_all(
$mode, '--check',
],
1,
- [qr/invalid/], # pg_upgrade prints errors on stdout :(
+ [qr/invalid/], # pg_upgrade prints errors on stdout :(
[qr//],
'invalid database causes failure');
rmtree($newnode->data_dir . "/pg_upgrade_output.d");
@@ -434,7 +472,7 @@ $result = $newnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index b943569050..c649477505 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -926,7 +926,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Encoding"));
if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
- " CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE d.datlocprovider WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Locale Provider"));
else
appendPQExpBuffer(&buf,
@@ -4974,7 +4974,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
if (pset.sversion >= 100000)
appendPQExpBuffer(&buf,
- " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Provider"));
else
appendPQExpBuffer(&buf,
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
index 14970a6a5f..4af4b98181 100644
--- a/src/bin/scripts/createdb.c
+++ b/src/bin/scripts/createdb.c
@@ -40,8 +40,9 @@ main(int argc, char *argv[])
{"locale", required_argument, NULL, 'l'},
{"maintenance-db", required_argument, NULL, 3},
{"locale-provider", required_argument, NULL, 4},
- {"icu-locale", required_argument, NULL, 5},
- {"icu-rules", required_argument, NULL, 6},
+ {"builtin-locale", required_argument, NULL, 5},
+ {"icu-locale", required_argument, NULL, 6},
+ {"icu-rules", required_argument, NULL, 7},
{NULL, 0, NULL, 0}
};
@@ -67,6 +68,7 @@ main(int argc, char *argv[])
char *lc_ctype = NULL;
char *locale = NULL;
char *locale_provider = NULL;
+ char *builtin_locale = NULL;
char *icu_locale = NULL;
char *icu_rules = NULL;
@@ -134,9 +136,12 @@ main(int argc, char *argv[])
locale_provider = pg_strdup(optarg);
break;
case 5:
- icu_locale = pg_strdup(optarg);
+ builtin_locale = pg_strdup(optarg);
break;
case 6:
+ icu_locale = pg_strdup(optarg);
+ break;
+ case 7:
icu_rules = pg_strdup(optarg);
break;
default:
@@ -216,6 +221,11 @@ main(int argc, char *argv[])
appendPQExpBufferStr(&sql, " LOCALE ");
appendStringLiteralConn(&sql, locale, conn);
}
+ if (builtin_locale)
+ {
+ appendPQExpBufferStr(&sql, " BUILTIN_LOCALE ");
+ appendStringLiteralConn(&sql, builtin_locale, conn);
+ }
if (lc_collate)
{
appendPQExpBufferStr(&sql, " LC_COLLATE ");
@@ -296,7 +306,7 @@ help(const char *progname)
printf(_(" --lc-ctype=LOCALE LC_CTYPE setting for the database\n"));
printf(_(" --icu-locale=LOCALE ICU locale setting for the database\n"));
printf(_(" --icu-rules=RULES ICU rules setting for the database\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" locale provider for the database's default collation\n"));
printf(_(" -O, --owner=OWNER database user to own the new database\n"));
printf(_(" -S, --strategy=STRATEGY database creation strategy wal_log or file_copy\n"));
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index 37e47b0078..3ba623f9d1 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -105,6 +105,84 @@ else
'create database with ICU fails since no ICU support');
}
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ 'tbuiltin1'
+ ],
+ 'create database with provider "builtin" fails without --locale');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin2'
+ ],
+ 'create database with provider "builtin" and locale "C"');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-collate=C',
+ 'tbuiltin3'
+ ],
+ 'create database with provider "builtin" and LC_COLLATE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-ctype=C',
+ 'tbuiltin4'
+ ],
+ 'create database with provider "builtin" and LC_CTYPE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E UTF-8', '--builtin-locale=C.UTF8',
+ 'tbuiltin5'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E LATIN1', '--builtin-locale=C.UTF-8',
+ 'tbuiltin6'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-locale=en',
+ 'tbuiltin7'
+ ],
+ 'create database with provider "builtin" and ICU_LOCALE="en"');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-rules=""',
+ 'tbuiltin8'
+ ],
+ 'create database with provider "builtin" and ICU_RULES=""');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template1', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin9'
+ ],
+ 'create database with provider "builtin" not matching template');
+
$node->command_fails([ 'createdb', 'foobar1' ],
'fails if database already exists');
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 7396ff10c4..938432e8a4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -23,9 +23,9 @@
descr => 'standard POSIX collation',
collname => 'POSIX', collprovider => 'c', collencoding => '-1',
collcollate => 'POSIX', collctype => 'POSIX' },
-{ oid => '962', descr => 'sorts by Unicode code point',
- collname => 'ucs_basic', collprovider => 'c', collencoding => '6',
- collcollate => 'C', collctype => 'C' },
+{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',
+ collname => 'ucs_basic', collprovider => 'b', collencoding => '6',
+ colllocale => 'C' },
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index a3e196fb53..5ce289d74b 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -68,6 +68,7 @@ MAKE_SYSCACHE(COLLOID, pg_collation_oid_index, 8);
#ifdef EXPOSE_TO_CLIENT_CODE
#define COLLPROVIDER_DEFAULT 'd'
+#define COLLPROVIDER_BUILTIN 'b'
#define COLLPROVIDER_ICU 'i'
#define COLLPROVIDER_LIBC 'c'
@@ -76,6 +77,8 @@ collprovider_name(char c)
{
switch (c)
{
+ case COLLPROVIDER_BUILTIN:
+ return "builtin";
case COLLPROVIDER_ICU:
return "icu";
case COLLPROVIDER_LIBC:
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 28c925b5af..4dfcb99872 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -76,6 +76,13 @@ struct pg_locale_struct
bool deterministic;
union
{
+ struct
+ {
+ const char *locale;
+ bool casemap_full;
+ bool titlecase;
+ bool properties_posix;
+ } builtin;
locale_t lt;
#ifdef USE_ICU
struct
@@ -112,7 +119,7 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
pg_locale_t locale);
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
size_t srclen, pg_locale_t locale);
-
+extern const char *builtin_validate_locale(int encoding, const char *loc_str);
extern void icu_validate_locale(const char *loc_str);
extern char *icu_language_tag(const char *loc_str, int elevel);
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
index 8a1fc12ec6..5f8ef16803 100644
--- a/src/test/icu/t/010_database.pl
+++ b/src/test/icu/t/010_database.pl
@@ -27,9 +27,8 @@ CREATE TABLE icu (def text, en text COLLATE "en-x-icu", upfirst text COLLATE upp
INSERT INTO icu VALUES ('a', 'a', 'a'), ('b', 'b', 'b'), ('A', 'A', 'A'), ('B', 'B', 'B');
});
-is( $node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
- qq(t),
- 'ICU unicode version defined');
+is($node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
+ qq(t), 'ICU unicode version defined');
is( $node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY def}),
qq(A
@@ -63,14 +62,13 @@ is( $node1->psql(
0,
"C locale works for ICU");
-# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
-# are specified
-is( $node1->psql(
- 'postgres',
- q{CREATE DATABASE dbicu2 LOCALE_PROVIDER icu LOCALE '@colStrength=primary'
- LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0 ENCODING UTF8}
- ),
- 0,
- "LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE are specified");
+my ($ret, $stdout, $stderr) = $node1->psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
+);
+isnt($ret, 0, "locale provider must match template: exit code not 0");
+like(
+ $stderr,
+ qr/ERROR: new locale provider \(builtin\) does not match locale provider of the template database \(icu\)/,
+ "locale provider must match template: error message");
done_testing();
diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out
index 0649564485..ece4a8e99d 100644
--- a/src/test/regress/expected/collate.out
+++ b/src/test/regress/expected/collate.out
@@ -650,6 +650,26 @@ EXPLAIN (COSTS OFF)
(3 rows)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+ b
+-----
+ ABD
+ Abc
+ abc
+ bbc
+(4 rows)
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+ERROR: invalid locale name "en_US" for builtin provider
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+ERROR: conflicting or redundant options
+DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
@@ -754,7 +774,7 @@ DETAIL: FROM cannot be specified together with any other options.
-- must get rid of them.
--
DROP SCHEMA collate_tests CASCADE;
-NOTICE: drop cascades to 19 other objects
+NOTICE: drop cascades to 21 other objects
DETAIL: drop cascades to table collate_test1
drop cascades to table collate_test_like
drop cascades to table collate_test2
@@ -771,6 +791,8 @@ drop cascades to function dup(anyelement)
drop cascades to table collate_test20
drop cascades to table collate_test21
drop cascades to table collate_test22
+drop cascades to collation builtin_c
+drop cascades to collation builtin_posix
drop cascades to collation mycoll2
drop cascades to table collate_test23
drop cascades to view collate_on_int
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
new file mode 100644
index 0000000000..58085f300c
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8.out
@@ -0,0 +1,287 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+SET client_encoding TO UTF8;
+--
+-- Test builtin UCS_BASIC locale.
+--
+CREATE COLLATION BUILTIN_UCS_BASIC ( provider = builtin, locale = 'UCS_BASIC' );
+CREATE TABLE builtin_test1 (
+ t TEXT COLLATE BUILTIN_UCS_BASIC
+);
+INSERT INTO builtin_test1 VALUES
+ ('abc DEF'),
+ ('ábc sßs DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test1;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+----------------+----------------+----------------+----------------+---------+---------------+-----------------+---------------
+ abc DEF | abc def | Abc Def | ABC DEF | 7 | 7 | 7 | 7
+ ábc sßs DÉF | ábc sßs déf | Ábc Sßs Déf | ÁBC SSSS DÉF | 14 | 14 | 14 | 14
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE builtin_test1;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE BUILTIN_UCS_BASIC); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE BUILTIN_UCS_BASIC); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UCS_BASIC; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UCS_BASIC;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UCS_BASIC; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
+DROP COLLATION BUILTIN_UCS_BASIC;
+--
+-- Test builtin C.UTF-8 locale.
+--
+CREATE COLLATION BUILTIN_C_UTF8 ( provider = builtin, locale = 'C.UTF-8' );
+CREATE TABLE builtin_test2 (
+ t TEXT COLLATE BUILTIN_C_UTF8
+);
+INSERT INTO builtin_test2 VALUES
+ ('abc DEF'),
+ ('ábc sßs DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test2;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+----------------+----------------+----------------+----------------+---------+---------------+-----------------+---------------
+ abc DEF | abc def | Abc Def | ABC DEF | 7 | 7 | 7 | 7
+ ábc sßs DÉF | ábc sßs déf | Ábc Sßs Déf | ÁBC SßS DÉF | 14 | 14 | 14 | 14
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | DŽxxdž DŽxxdž DŽxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE builtin_test2;
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ ασ
+(1 row)
+
+SELECT lower('ΑͺΣͺ' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ αͺσͺ
+(1 row)
+
+SELECT lower('Α΄Σ΄' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ α΄σ΄
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' ~ '[[:punct:]]' COLLATE BUILTIN_C_UTF8; -- symbols are punctuation in posix
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' !~ '\d' COLLATE BUILTIN_C_UTF8; -- only 0-9 considered digits in posix
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_C_UTF8; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
+DROP COLLATION BUILTIN_C_UTF8;
diff --git a/src/test/regress/expected/collate.utf8_1.out b/src/test/regress/expected/collate.utf8_1.out
new file mode 100644
index 0000000000..e73fdf50c3
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8_1.out
@@ -0,0 +1,8 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 1d8a414eea..e48cb4b7a3 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,9 +78,9 @@ test: brin_bloom brin_multi
# psql depends on create_am
# amutils depends on geometry, create_index_spgist, hash_index, brin
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps
-# collate.*.utf8 tests cannot be run in parallel with each other
+# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252
# ----------
diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql
index c3d40fc195..01d5c69fe4 100644
--- a/src/test/regress/sql/collate.sql
+++ b/src/test/regress/sql/collate.sql
@@ -244,6 +244,16 @@ EXPLAIN (COSTS OFF)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
new file mode 100644
index 0000000000..747fc63bf4
--- /dev/null
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -0,0 +1,122 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+SET client_encoding TO UTF8;
+
+--
+-- Test builtin UCS_BASIC locale.
+--
+
+CREATE COLLATION BUILTIN_UCS_BASIC ( provider = builtin, locale = 'UCS_BASIC' );
+
+CREATE TABLE builtin_test1 (
+ t TEXT COLLATE BUILTIN_UCS_BASIC
+);
+INSERT INTO builtin_test1 VALUES
+ ('abc DEF'),
+ ('ábc sßs DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test1;
+
+DROP TABLE builtin_test1;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE BUILTIN_UCS_BASIC); -- 03A3
+SELECT lower('0Σ' COLLATE BUILTIN_UCS_BASIC); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UCS_BASIC; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT '൧' ~ '\d' COLLATE BUILTIN_UCS_BASIC;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UCS_BASIC; -- same as above with cases reversed
+
+DROP COLLATION BUILTIN_UCS_BASIC;
+
+--
+-- Test builtin C.UTF-8 locale.
+--
+
+CREATE COLLATION BUILTIN_C_UTF8 ( provider = builtin, locale = 'C.UTF-8' );
+
+CREATE TABLE builtin_test2 (
+ t TEXT COLLATE BUILTIN_C_UTF8
+);
+INSERT INTO builtin_test2 VALUES
+ ('abc DEF'),
+ ('ábc sßs DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test2;
+
+DROP TABLE builtin_test2;
+
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE BUILTIN_C_UTF8);
+SELECT lower('ΑͺΣͺ' COLLATE BUILTIN_C_UTF8);
+SELECT lower('Α΄Σ΄' COLLATE BUILTIN_C_UTF8);
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '=' ~ '[[:punct:]]' COLLATE BUILTIN_C_UTF8; -- symbols are punctuation in posix
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '൧' !~ '\d' COLLATE BUILTIN_C_UTF8; -- only 0-9 considered digits in posix
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_C_UTF8;
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_C_UTF8;
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_C_UTF8;
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_C_UTF8;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_C_UTF8; -- same as above with cases reversed
+
+DROP COLLATION BUILTIN_C_UTF8;
--
2.34.1
[text/x-patch] v18-0006-Change-collation-UCS_BASIC-to-use-Unicode-semant.patch (11.0K, ../../[email protected]/7-v18-0006-Change-collation-UCS_BASIC-to-use-Unicode-semant.patch)
download | inline diff:
From 595725068183a07391e4f097792e84b4522771e9 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 19 Feb 2024 14:43:15 -0800
Subject: [PATCH v18 6/6] Change collation UCS_BASIC to use Unicode semantics.
The SQL standard defines UCS_BASIC to sort by code point order, but
the character behavior (e.g. for LOWER() and UPPER()) is defined in
terms of Unicode.
The pre-existing sort order of UCS_BASIC is correct, and is not
changed by this commit. The character behavior is changed to use
Unicode rather than C semantics. This affects case mapping (LOWER(),
UPPER(), and INITCAP()) as well as pattern matching (LIKE and
regexes).
Also add standard collation PG_C_UTF8 which uses the builtin locale
C.UTF-8.
---
doc/src/sgml/charset.sgml | 30 +++++++++++---
src/include/catalog/pg_collation.dat | 5 ++-
src/test/regress/expected/collate.utf8.out | 44 ++++++++++-----------
src/test/regress/sql/collate.utf8.sql | 46 ++++++++++------------
4 files changed, 71 insertions(+), 54 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 2abd898115..01a3657c7f 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -865,11 +865,31 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<listitem>
<para>
This SQL standard collation sorts by Unicode code point. Behavior is
- efficient and stable across all versions. Case mapping and pattern
- matching behavior is based on simple ASCII semantics. It is only
- available for encoding <literal>UTF8</literal>. (This collation has
- the same behavior as the libc locale specification
- <literal>C</literal> in <literal>UTF8</literal> encoding.)
+ efficient and stable within a <productname>Postgres</productname>
+ major version. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. It is only available for encoding
+ <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PG_C_UTF8</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point. Behavior is efficient and
+ stable within a <productname>Postgres</productname> major version.
+ For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode simple case mapping. For pattern matching (including regular
+ expressions), it uses the POSIX Compatible variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. This collation is only available for encoding
+ <literal>UTF8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 938432e8a4..f12c84e9ae 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -25,10 +25,13 @@
collcollate => 'POSIX', collctype => 'POSIX' },
{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',
collname => 'ucs_basic', collprovider => 'b', collencoding => '6',
- colllocale => 'C' },
+ colllocale => 'UCS_BASIC' },
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
+{ oid => '970', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
+ collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
+ colllocale => 'C.UTF8' },
]
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index 58085f300c..1f903ed561 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -11,9 +11,8 @@ SET client_encoding TO UTF8;
--
-- Test builtin UCS_BASIC locale.
--
-CREATE COLLATION BUILTIN_UCS_BASIC ( provider = builtin, locale = 'UCS_BASIC' );
CREATE TABLE builtin_test1 (
- t TEXT COLLATE BUILTIN_UCS_BASIC
+ t TEXT COLLATE UCS_BASIC
);
INSERT INTO builtin_test1 VALUES
('abc DEF'),
@@ -41,130 +40,129 @@ SELECT
DROP TABLE builtin_test1;
-- test Final_Sigma
-SELECT lower('ΑΣ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3
+SELECT lower('ΑΣ' COLLATE UCS_BASIC); -- 0391 03A3
lower
-------
ας
(1 row)
-SELECT lower('ΑΣ0' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0030
+SELECT lower('ΑΣ0' COLLATE UCS_BASIC); -- 0391 03A3 0030
lower
-------
ας0
(1 row)
-SELECT lower('ἈΣ̓' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343
+SELECT lower('ἈΣ̓' COLLATE UCS_BASIC); -- 0391 0343 03A3 0343
lower
-------
ἀς̓
(1 row)
-SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345
+SELECT lower('ᾼΣͅ' COLLATE UCS_BASIC); -- 0391 0345 03A3 0345
lower
-------
ᾳςͅ
(1 row)
-- test !Final_Sigma
-SELECT lower('Σ' COLLATE BUILTIN_UCS_BASIC); -- 03A3
+SELECT lower('Σ' COLLATE UCS_BASIC); -- 03A3
lower
-------
σ
(1 row)
-SELECT lower('0Σ' COLLATE BUILTIN_UCS_BASIC); -- 0030 03A3
+SELECT lower('0Σ' COLLATE UCS_BASIC); -- 0030 03A3
lower
-------
0σ
(1 row)
-SELECT lower('ΑΣΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0391
+SELECT lower('ΑΣΑ' COLLATE UCS_BASIC); -- 0391 03A3 0391
lower
-------
ασα
(1 row)
-SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343 0391
+SELECT lower('ἈΣ̓Α' COLLATE UCS_BASIC); -- 0391 0343 03A3 0343 0391
lower
-------
ἀσ̓α
(1 row)
-SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345 0391
+SELECT lower('ᾼΣͅΑ' COLLATE UCS_BASIC); -- 0391 0345 03A3 0345 0391
lower
-------
ᾳσͅα
(1 row)
-- properties
-SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT '@' !~ '[[:alnum:]]' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UCS_BASIC; -- symbols are not punctuation
+SELECT '=' !~ '[[:punct:]]' COLLATE UCS_BASIC; -- symbols are not punctuation
?column?
----------
t
(1 row)
-SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT '൧' ~ '\d' COLLATE BUILTIN_UCS_BASIC;
+SELECT '൧' ~ '\d' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-- case mapping
-SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xYz' ~* 'XyZ' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xAb' ~* '[W-Y]' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xAb' !~* '[c-d]' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'Δ' ~* '[α-λ]' COLLATE UCS_BASIC;
?column?
----------
t
(1 row)
-SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UCS_BASIC; -- same as above with cases reversed
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE UCS_BASIC; -- same as above with cases reversed
?column?
----------
t
(1 row)
-DROP COLLATION BUILTIN_UCS_BASIC;
--
-- Test builtin C.UTF-8 locale.
--
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index 747fc63bf4..26e3d0ef88 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -15,10 +15,8 @@ SET client_encoding TO UTF8;
-- Test builtin UCS_BASIC locale.
--
-CREATE COLLATION BUILTIN_UCS_BASIC ( provider = builtin, locale = 'UCS_BASIC' );
-
CREATE TABLE builtin_test1 (
- t TEXT COLLATE BUILTIN_UCS_BASIC
+ t TEXT COLLATE UCS_BASIC
);
INSERT INTO builtin_test1 VALUES
('abc DEF'),
@@ -39,36 +37,34 @@ SELECT
DROP TABLE builtin_test1;
-- test Final_Sigma
-SELECT lower('ΑΣ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3
-SELECT lower('ΑΣ0' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0030
-SELECT lower('ἈΣ̓' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343
-SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345
+SELECT lower('ΑΣ' COLLATE UCS_BASIC); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE UCS_BASIC); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE UCS_BASIC); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE UCS_BASIC); -- 0391 0345 03A3 0345
-- test !Final_Sigma
-SELECT lower('Σ' COLLATE BUILTIN_UCS_BASIC); -- 03A3
-SELECT lower('0Σ' COLLATE BUILTIN_UCS_BASIC); -- 0030 03A3
-SELECT lower('ΑΣΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 03A3 0391
-SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UCS_BASIC); -- 0391 0343 03A3 0343 0391
-SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UCS_BASIC); -- 0391 0345 03A3 0345 0391
+SELECT lower('Σ' COLLATE UCS_BASIC); -- 03A3
+SELECT lower('0Σ' COLLATE UCS_BASIC); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE UCS_BASIC); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE UCS_BASIC); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE UCS_BASIC); -- 0391 0345 03A3 0345 0391
-- properties
-SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
-SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UCS_BASIC;
-SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UCS_BASIC;
-SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UCS_BASIC; -- symbols are not punctuation
-SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UCS_BASIC;
-SELECT '൧' ~ '\d' COLLATE BUILTIN_UCS_BASIC;
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE UCS_BASIC;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE UCS_BASIC;
+SELECT '@' !~ '[[:alnum:]]' COLLATE UCS_BASIC;
+SELECT '=' !~ '[[:punct:]]' COLLATE UCS_BASIC; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE UCS_BASIC;
+SELECT '൧' ~ '\d' COLLATE UCS_BASIC;
-- case mapping
-SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UCS_BASIC;
-SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UCS_BASIC;
-SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UCS_BASIC;
-SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UCS_BASIC;
-SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UCS_BASIC; -- same as above with cases reversed
-
-DROP COLLATION BUILTIN_UCS_BASIC;
+SELECT 'xYz' ~* 'XyZ' COLLATE UCS_BASIC;
+SELECT 'xAb' ~* '[W-Y]' COLLATE UCS_BASIC;
+SELECT 'xAb' !~* '[c-d]' COLLATE UCS_BASIC;
+SELECT 'Δ' ~* '[α-λ]' COLLATE UCS_BASIC;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE UCS_BASIC; -- same as above with cases reversed
--
-- Test builtin C.UTF-8 locale.
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-01 05:05 ` Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-01 05:05 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Mon, 2024-02-26 at 19:01 -0800, Jeff Davis wrote:
> * Right now you can't mix all of the full case mapping behavior with
> INITCAP(), it just does simple titlecase mapping. I'm not sure we
> want
> to get too fancy here; after all, INITCAP() is not a SQL standard
> function and it's documented in a narrow fashion that doesn't seem to
> leave a lot of room to be very smart. ICU does a few extra things
> beyond what I did:
> - it accepts a word break iterator to the case conversion function
> - it provides some built-in word break iterators
> - it also has some configurable "break adjustment" behavior[1][2]
> which re-aligns the start of the word, and I'm not entirely sure why
> that isn't done in the word break iterator or the titlecasing rules
Attached v19 which addresses this issue. It does proper Unicode
titlecasing with a word boundary iterator as an argument. For initcap,
it just uses a simple word boundary iterator that breaks whenever
isalnum() changes.
It came out cleaner this way, ultimately, and it feels more complete
even though the behavior isn't much different. It's also easier to
comment the relationship of the functions to Unicode. I removed
CaseKind from the public API but still use it internally to avoid code
duplication.
I made one other change, which is that (for now) I undid the UCS_BASIC
change until we are sure we want to change it. Instead, I have builtin
collations PG_C_UTF8 and PG_UNICODE_FAST. I used the name "FAST" to
indicate that the collation uses fast memcmp() rather than a real
collation, but the Unicode character support is all there (including
full case mapping). I'm open to suggestion here on naming.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v19-0001-Documentation-update-for-Standard-Collations.patch (5.0K, ../../[email protected]/2-v19-0001-Documentation-update-for-Standard-Collations.patch)
download | inline diff:
From eb027f109c0a4bc5bf9b74016eec30c2eeae4c83 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 19 Feb 2024 15:21:39 -0800
Subject: [PATCH v19 1/6] Documentation update for Standard Collations.
---
doc/src/sgml/charset.sgml | 79 ++++++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 31 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 74783d148f..4422b0cc92 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -788,55 +788,72 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
<title>Standard Collations</title>
<para>
- On all platforms, the collations named <literal>default</literal>,
- <literal>C</literal>, and <literal>POSIX</literal> are available. Additional
- collations may be available depending on operating system support.
- The <literal>default</literal> collation selects the <symbol>LC_COLLATE</symbol>
- and <symbol>LC_CTYPE</symbol> values specified at database creation time.
- The <literal>C</literal> and <literal>POSIX</literal> collations both specify
- <quote>traditional C</quote> behavior, in which only the ASCII letters
- <quote><literal>A</literal></quote> through <quote><literal>Z</literal></quote>
- are treated as letters, and sorting is done strictly by character
- code byte values.
- </para>
-
- <note>
- <para>
- The <literal>C</literal> and <literal>POSIX</literal> locales may behave
- differently depending on the database encoding.
- </para>
- </note>
-
- <para>
- Additionally, two SQL standard collation names are available:
+ On all platforms, the collations following collations are supported:
<variablelist>
<varlistentry>
- <term><literal>unicode</literal></term>
+ <term><literal>UNICODE</literal></term>
<listitem>
<para>
- This collation sorts using the Unicode Collation Algorithm with the
- Default Unicode Collation Element Table. It is available in all
- encodings. ICU support is required to use this collation. (This
- collation has the same behavior as the ICU root locale; see <xref
+ This SQL standard collation sorts using the Unicode Collation
+ Algorithm with the Default Unicode Collation Element Table. It is
+ available in all encodings. ICU support is required to use this
+ collation, and behavior may change if Postgres is built with a
+ different version of ICU. (This collation has the same behavior as
+ the ICU root locale; see <xref
linkend="collation-managing-predefined-icu-und-x-icu"/>.)
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><literal>ucs_basic</literal></term>
+ <term><literal>UCS_BASIC</literal></term>
<listitem>
<para>
- This collation sorts by Unicode code point. It is only available for
- encoding <literal>UTF8</literal>. (This collation has the same
- behavior as the libc locale specification <literal>C</literal> in
- <literal>UTF8</literal> encoding.)
+ This SQL standard collation sorts by Unicode code point. Behavior is
+ efficient and stable across all versions. Case mapping and pattern
+ matching behavior is based on simple ASCII semantics. It is only
+ available for encoding <literal>UTF8</literal>. (This collation has
+ the same behavior as the libc locale specification
+ <literal>C</literal> in <literal>UTF8</literal> encoding.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
+ <listitem>
+ <para>
+ The <literal>C</literal> and <literal>POSIX</literal> collations both
+ specify <quote>traditional C</quote> behavior, in which only the ASCII
+ letters <quote><literal>A</literal></quote> through
+ <quote><literal>Z</literal></quote> are treated as letters, and
+ sorting is done strictly by character code byte values. Case mapping
+ and pattern matching behavior is based on simple ASCII
+ semantics. Behavior is efficient and stable across all versions for a
+ given database encoding, but behavior may vary between different
+ database encodings.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>default</literal></term>
+ <listitem>
+ <para>
+ The <literal>default</literal> collation selects the locale specified
+ at database creation time.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
+
+ <para>
+ Additional collations may be available depending on operating system
+ support. The efficiency and stability of these additional collations
+ depend on the collation provider, the provider version, and the locale.
+ </para>
</sect3>
<sect3 id="collation-managing-predefined">
--
2.34.1
[text/x-patch] v19-0002-Add-Unicode-property-tables.patch (105.9K, ../../[email protected]/3-v19-0002-Add-Unicode-property-tables.patch)
download | inline diff:
From 8377c65a36509cfbae08664b445738a89237033d Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 18 Nov 2023 15:34:24 -0800
Subject: [PATCH v19 2/6] Add Unicode property tables.
Provide functions to test for regex character classes (e.g. 'alpha',
'punct') using Unicode properties.
---
src/common/unicode/Makefile | 6 +-
src/common/unicode/category_test.c | 225 +-
.../generate-unicode_category_table.pl | 308 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_category.c | 289 +-
src/include/common/unicode_category.h | 27 +-
src/include/common/unicode_category_table.h | 3030 ++++++++++++++++-
7 files changed, 3795 insertions(+), 94 deletions(-)
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index 04d81dd5cb..27f0408d8b 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -29,13 +29,13 @@ update-unicode: unicode_category_table.h unicode_east_asian_fw_table.h unicode_n
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
$(PERL) $< --version $(UNICODE_VERSION)
-unicode_category_table.h: generate-unicode_category_table.pl UnicodeData.txt
+unicode_category_table.h: generate-unicode_category_table.pl DerivedCoreProperties.txt PropList.txt UnicodeData.txt
$(PERL) $<
# Generation of conversion tables used for string normalization with
@@ -82,4 +82,4 @@ clean:
rm -f $(OBJS) category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/category_test.c b/src/common/unicode/category_test.c
index f1aaac0f61..8d1732b448 100644
--- a/src/common/unicode/category_test.c
+++ b/src/common/unicode/category_test.c
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------
* category_test.c
- * Program to test Unicode general category functions.
+ * Program to test Unicode general category and character properties.
*
* Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
*
@@ -14,17 +14,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
#ifdef USE_ICU
#include <unicode/uchar.h>
#endif
-#include "common/unicode_category.h"
+#include <wctype.h>
+
#include "common/unicode_version.h"
+#include "common/unicode_category.h"
+
+static int pg_unicode_version = 0;
+#ifdef USE_ICU
+static int icu_unicode_version = 0;
+#endif
/*
* Parse version into integer for easy comparison.
*/
-#ifdef USE_ICU
static int
parse_unicode_version(const char *version)
{
@@ -39,57 +44,175 @@ parse_unicode_version(const char *version)
return major * 100 + minor;
}
-#endif
+#ifdef USE_ICU
/*
- * Exhaustively test that the Unicode category for each codepoint matches that
- * returned by ICU.
+ * Test Postgres Unicode tables by comparing with ICU. Test the General
+ * Category, as well as the properties Alphabetic, Lowercase, Uppercase,
+ * White_Space, and Hex_Digit.
*/
-int
-main(int argc, char **argv)
+static void
+icu_test()
{
-#ifdef USE_ICU
- int pg_unicode_version = parse_unicode_version(PG_UNICODE_VERSION);
- int icu_unicode_version = parse_unicode_version(U_UNICODE_VERSION);
+ int successful = 0;
int pg_skipped_codepoints = 0;
int icu_skipped_codepoints = 0;
- printf("category_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
- printf("category_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
-
- for (UChar32 code = 0; code <= 0x10ffff; code++)
+ for (pg_wchar code = 0; code <= 0x10ffff; code++)
{
uint8_t pg_category = unicode_category(code);
uint8_t icu_category = u_charType(code);
+ /* Property tests */
+ bool prop_alphabetic = pg_u_prop_alphabetic(code);
+ bool prop_lowercase = pg_u_prop_lowercase(code);
+ bool prop_uppercase = pg_u_prop_uppercase(code);
+ bool prop_cased = pg_u_prop_cased(code);
+ bool prop_case_ignorable = pg_u_prop_case_ignorable(code);
+ bool prop_white_space = pg_u_prop_white_space(code);
+ bool prop_hex_digit = pg_u_prop_hex_digit(code);
+ bool prop_join_control = pg_u_prop_join_control(code);
+
+ bool icu_prop_alphabetic = u_hasBinaryProperty(
+ code, UCHAR_ALPHABETIC);
+ bool icu_prop_lowercase = u_hasBinaryProperty(
+ code, UCHAR_LOWERCASE);
+ bool icu_prop_uppercase = u_hasBinaryProperty(
+ code, UCHAR_UPPERCASE);
+ bool icu_prop_cased = u_hasBinaryProperty(
+ code, UCHAR_CASED);
+ bool icu_prop_case_ignorable = u_hasBinaryProperty(
+ code, UCHAR_CASE_IGNORABLE);
+ bool icu_prop_white_space = u_hasBinaryProperty(
+ code, UCHAR_WHITE_SPACE);
+ bool icu_prop_hex_digit = u_hasBinaryProperty(
+ code, UCHAR_HEX_DIGIT);
+ bool icu_prop_join_control = u_hasBinaryProperty(
+ code, UCHAR_JOIN_CONTROL);
+
+ /*
+ * Compare with ICU for character classes using:
+ *
+ * https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/uchar_8h.html#details
+ *
+ * which describes how to use ICU to test for membership in regex
+ * character classes.
+ *
+ * NB: the document suggests testing for some properties such as
+ * UCHAR_POSIX_ALNUM, but that doesn't mean that we're testing for the
+ * "POSIX Compatible" character classes.
+ */
+ bool isalpha = pg_u_isalpha(code);
+ bool islower = pg_u_islower(code);
+ bool isupper = pg_u_isupper(code);
+ bool ispunct = pg_u_ispunct(code, false);
+ bool isdigit = pg_u_isdigit(code, false);
+ bool isxdigit = pg_u_isxdigit(code, false);
+ bool isalnum = pg_u_isalnum(code, false);
+ bool isspace = pg_u_isspace(code);
+ bool isblank = pg_u_isblank(code);
+ bool iscntrl = pg_u_iscntrl(code);
+ bool isgraph = pg_u_isgraph(code);
+ bool isprint = pg_u_isprint(code);
+
+ bool icu_isalpha = u_isUAlphabetic(code);
+ bool icu_islower = u_isULowercase(code);
+ bool icu_isupper = u_isUUppercase(code);
+ bool icu_ispunct = u_ispunct(code);
+ bool icu_isdigit = u_isdigit(code);
+ bool icu_isxdigit = u_hasBinaryProperty(code,
+ UCHAR_POSIX_XDIGIT);
+ bool icu_isalnum = u_hasBinaryProperty(code,
+ UCHAR_POSIX_ALNUM);
+ bool icu_isspace = u_isUWhiteSpace(code);
+ bool icu_isblank = u_isblank(code);
+ bool icu_iscntrl = icu_category == PG_U_CONTROL;
+ bool icu_isgraph = u_hasBinaryProperty(code,
+ UCHAR_POSIX_GRAPH);
+ bool icu_isprint = u_hasBinaryProperty(code,
+ UCHAR_POSIX_PRINT);
+
+ /*
+ * A version mismatch means that some assigned codepoints in the newer
+ * version may be unassigned in the older version. That's OK, though
+ * the test will not cover those codepoints marked unassigned in the
+ * older version (that is, it will no longer be an exhaustive test).
+ */
+ if (pg_category == PG_U_UNASSIGNED &&
+ icu_category != PG_U_UNASSIGNED &&
+ pg_unicode_version < icu_unicode_version)
+ {
+ pg_skipped_codepoints++;
+ continue;
+ }
+
+ if (icu_category == PG_U_UNASSIGNED &&
+ pg_category != PG_U_UNASSIGNED &&
+ icu_unicode_version < pg_unicode_version)
+ {
+ icu_skipped_codepoints++;
+ continue;
+ }
+
if (pg_category != icu_category)
{
- /*
- * A version mismatch means that some assigned codepoints in the
- * newer version may be unassigned in the older version. That's
- * OK, though the test will not cover those codepoints marked
- * unassigned in the older version (that is, it will no longer be
- * an exhaustive test).
- */
- if (pg_category == PG_U_UNASSIGNED &&
- pg_unicode_version < icu_unicode_version)
- pg_skipped_codepoints++;
- else if (icu_category == PG_U_UNASSIGNED &&
- icu_unicode_version < pg_unicode_version)
- icu_skipped_codepoints++;
- else
- {
- printf("category_test: FAILURE for codepoint 0x%06x\n", code);
- printf("category_test: Postgres category: %02d %s %s\n", pg_category,
- unicode_category_abbrev(pg_category),
- unicode_category_string(pg_category));
- printf("category_test: ICU category: %02d %s %s\n", icu_category,
- unicode_category_abbrev(icu_category),
- unicode_category_string(icu_category));
- printf("\n");
- exit(1);
- }
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres category: %02d %s %s\n", pg_category,
+ unicode_category_abbrev(pg_category),
+ unicode_category_string(pg_category));
+ printf("category_test: ICU category: %02d %s %s\n", icu_category,
+ unicode_category_abbrev(icu_category),
+ unicode_category_string(icu_category));
+ printf("\n");
+ exit(1);
}
+
+ if (prop_alphabetic != icu_prop_alphabetic ||
+ prop_lowercase != icu_prop_lowercase ||
+ prop_uppercase != icu_prop_uppercase ||
+ prop_cased != icu_prop_cased ||
+ prop_case_ignorable != icu_prop_case_ignorable ||
+ prop_white_space != icu_prop_white_space ||
+ prop_hex_digit != icu_prop_hex_digit ||
+ prop_join_control != icu_prop_join_control)
+ {
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres property alphabetic/lowercase/uppercase/cased/case_ignorable/white_space/hex_digit/join_control: %d/%d/%d/%d/%d/%d/%d/%d\n",
+ prop_alphabetic, prop_lowercase, prop_uppercase,
+ prop_cased, prop_case_ignorable,
+ prop_white_space, prop_hex_digit, prop_join_control);
+ printf("category_test: ICU property alphabetic/lowercase/uppercase/cased/case_ignorable/white_space/hex_digit/join_control: %d/%d/%d/%d/%d/%d/%d/%d\n",
+ icu_prop_alphabetic, icu_prop_lowercase, icu_prop_uppercase,
+ icu_prop_cased, icu_prop_case_ignorable,
+ icu_prop_white_space, icu_prop_hex_digit, icu_prop_join_control);
+ printf("\n");
+ exit(1);
+ }
+
+ if (isalpha != icu_isalpha ||
+ islower != icu_islower ||
+ isupper != icu_isupper ||
+ ispunct != icu_ispunct ||
+ isdigit != icu_isdigit ||
+ isxdigit != icu_isxdigit ||
+ isalnum != icu_isalnum ||
+ isspace != icu_isspace ||
+ isblank != icu_isblank ||
+ iscntrl != icu_iscntrl ||
+ isgraph != icu_isgraph ||
+ isprint != icu_isprint)
+ {
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres class alpha/lower/upper/punct/digit/xdigit/alnum/space/blank/cntrl/graph/print: %d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n",
+ isalpha, islower, isupper, ispunct, isdigit, isxdigit, isalnum, isspace, isblank, iscntrl, isgraph, isprint);
+ printf("category_test: ICU class alpha/lower/upper/punct/digit/xdigit/alnum/space/blank/cntrl/graph/print: %d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n",
+ icu_isalpha, icu_islower, icu_isupper, icu_ispunct, icu_isdigit, icu_isxdigit, icu_isalnum, icu_isspace, icu_isblank, icu_iscntrl, icu_isgraph, icu_isprint);
+ printf("\n");
+ exit(1);
+ }
+
+ if (pg_category != PG_U_UNASSIGNED)
+ successful++;
}
if (pg_skipped_codepoints > 0)
@@ -99,10 +222,22 @@ main(int argc, char **argv)
printf("category_test: skipped %d codepoints unassigned in ICU due to Unicode version mismatch\n",
icu_skipped_codepoints);
- printf("category_test: success\n");
- exit(0);
+ printf("category_test: ICU test: %d codepoints successful\n", successful);
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+ pg_unicode_version = parse_unicode_version(PG_UNICODE_VERSION);
+ printf("category_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
+
+#ifdef USE_ICU
+ icu_unicode_version = parse_unicode_version(U_UNICODE_VERSION);
+ printf("category_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
+
+ icu_test();
#else
- printf("category_test: ICU support required for test; skipping\n");
- exit(0);
+ printf("category_test: ICU not available; skipping\n");
#endif
}
diff --git a/src/common/unicode/generate-unicode_category_table.pl b/src/common/unicode/generate-unicode_category_table.pl
index a50c87b7e9..364e87201e 100644
--- a/src/common/unicode/generate-unicode_category_table.pl
+++ b/src/common/unicode/generate-unicode_category_table.pl
@@ -48,21 +48,30 @@ while (my $line = <$FH>)
my $category = $elts[2];
die "codepoint out of range" if $code > 0x10FFFF;
- die "unassigned codepoint in UnicodeData.txt" if $category eq $CATEGORY_UNASSIGNED;
+ die "unassigned codepoint in UnicodeData.txt"
+ if $category eq $CATEGORY_UNASSIGNED;
- if (!defined($range_start)) {
+ if (!defined($range_start))
+ {
my $code_str = sprintf "0x%06x", $code;
- die if defined($range_end) || defined($range_category) || defined($gap_category);
+ die
+ if defined($range_end)
+ || defined($range_category)
+ || defined($gap_category);
die "unexpected first entry <..., Last>" if ($name =~ /Last>/);
- die "expected 0x000000 for first entry, got $code_str" if $code != 0x000000;
+ die "expected 0x000000 for first entry, got $code_str"
+ if $code != 0x000000;
# initialize
$range_start = $code;
$range_end = $code;
$range_category = $category;
- if ($name =~ /<.*, First>$/) {
+ if ($name =~ /<.*, First>$/)
+ {
$gap_category = $category;
- } else {
+ }
+ else
+ {
$gap_category = $CATEGORY_UNASSIGNED;
}
next;
@@ -71,10 +80,17 @@ while (my $line = <$FH>)
# Gap in codepoints detected. If it's a different category than
# the current range, emit the current range and initialize a new
# range representing the gap.
- if ($range_end + 1 != $code && $range_category ne $gap_category) {
- if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+ if ($range_end + 1 != $code && $range_category ne $gap_category)
+ {
+ if ($range_category ne $CATEGORY_UNASSIGNED)
+ {
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
$range_start = $range_end + 1;
$range_end = $code - 1;
@@ -82,27 +98,39 @@ while (my $line = <$FH>)
}
# different category; new range
- if ($range_category ne $category) {
- if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+ if ($range_category ne $category)
+ {
+ if ($range_category ne $CATEGORY_UNASSIGNED)
+ {
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
$range_start = $code;
$range_end = $code;
$range_category = $category;
}
- if ($name =~ /<.*, First>$/) {
- die "<..., First> entry unexpectedly follows another <..., First> entry"
+ if ($name =~ /<.*, First>$/)
+ {
+ die
+ "<..., First> entry unexpectedly follows another <..., First> entry"
if $gap_category ne $CATEGORY_UNASSIGNED;
$gap_category = $category;
}
- elsif ($name =~ /<.*, Last>$/) {
- die "<..., First> and <..., Last> entries have mismatching general category"
+ elsif ($name =~ /<.*, Last>$/)
+ {
+ die
+ "<..., First> and <..., Last> entries have mismatching general category"
if $gap_category ne $category;
$gap_category = $CATEGORY_UNASSIGNED;
}
- else {
+ else
+ {
die "unexpected entry found between <..., First> and <..., Last>"
if $gap_category ne $CATEGORY_UNASSIGNED;
}
@@ -115,13 +143,17 @@ die "<..., First> entry with no corresponding <..., Last> entry"
if $gap_category ne $CATEGORY_UNASSIGNED;
# emit final range
-if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+if ($range_category ne $CATEGORY_UNASSIGNED)
+{
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
-my $num_ranges = scalar @category_ranges;
-
# See: https://www.unicode.org/reports/tr44/#General_Category_Values
my $categories = {
Cn => 'PG_U_UNASSIGNED',
@@ -156,11 +188,116 @@ my $categories = {
Pf => 'PG_U_FINAL_PUNCTUATION'
};
-# Start writing out the output files
+# Find White_Space and Hex_Digit characters
+my @white_space = ();
+my @hex_digits = ();
+my @join_control = ();
+open($FH, '<', "$output_path/PropList.txt")
+ or die "Could not open $output_path/PropList.txt: $!.";
+while (my $line = <$FH>)
+{
+ my $pattern = qr/([0-9A-F\.]+)\s*;\s*(\w+)\s*#.*/s;
+ next unless $line =~ $pattern;
+
+ my $code = $line =~ s/$pattern/$1/rg;
+ my $property = $line =~ s/$pattern/$2/rg;
+ my $start;
+ my $end;
+
+ if ($code =~ /\.\./)
+ {
+ # code range
+ my @sp = split /\.\./, $code;
+ $start = hex($sp[0]);
+ $end = hex($sp[1]);
+ }
+ else
+ {
+ # single code point
+ $start = hex($code);
+ $end = hex($code);
+ }
+
+ if ($property eq "White_Space")
+ {
+ push @white_space, { start => $start, end => $end };
+ }
+ elsif ($property eq "Hex_Digit")
+ {
+ push @hex_digits, { start => $start, end => $end };
+ }
+ elsif ($property eq "Join_Control")
+ {
+ push @join_control, { start => $start, end => $end };
+ }
+}
+
+# Find Alphabetic, Lowercase, and Uppercase characters
+my @alphabetic = ();
+my @lowercase = ();
+my @uppercase = ();
+my @case_ignorable = ();
+open($FH, '<', "$output_path/DerivedCoreProperties.txt")
+ or die "Could not open $output_path/DerivedCoreProperties.txt: $!.";
+while (my $line = <$FH>)
+{
+ my $pattern = qr/^([0-9A-F\.]+)\s*;\s*(\w+)\s*#.*$/s;
+ next unless $line =~ $pattern;
+
+ my $code = $line =~ s/$pattern/$1/rg;
+ my $property = $line =~ s/$pattern/$2/rg;
+ my $start;
+ my $end;
+
+ if ($code =~ /\.\./)
+ {
+ # code range
+ my @sp = split /\.\./, $code;
+ die "line: {$line} code: {$code} sp[0] {$sp[0]} sp[1] {$sp[1]}"
+ unless $sp[0] =~ /^[0-9A-F]+$/ && $sp[1] =~ /^[0-9A-F]+$/;
+ $start = hex($sp[0]);
+ $end = hex($sp[1]);
+ }
+ else
+ {
+ die "line: {$line} code: {$code}" unless $code =~ /^[0-9A-F]+$/;
+ # single code point
+ $start = hex($code);
+ $end = hex($code);
+ }
+
+ if ($property eq "Alphabetic")
+ {
+ push @alphabetic, { start => $start, end => $end };
+ }
+ elsif ($property eq "Lowercase")
+ {
+ push @lowercase, { start => $start, end => $end };
+ }
+ elsif ($property eq "Uppercase")
+ {
+ push @uppercase, { start => $start, end => $end };
+ }
+ elsif ($property eq "Case_Ignorable")
+ {
+ push @case_ignorable, { start => $start, end => $end };
+ }
+}
+
+my $num_category_ranges = scalar @category_ranges;
+my $num_alphabetic_ranges = scalar @alphabetic;
+my $num_lowercase_ranges = scalar @lowercase;
+my $num_uppercase_ranges = scalar @uppercase;
+my $num_case_ignorable_ranges = scalar @case_ignorable;
+my $num_white_space_ranges = scalar @white_space;
+my $num_hex_digit_ranges = scalar @hex_digits;
+my $num_join_control_ranges = scalar @join_control;
+
+# Start writing out the output file
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
-print $OT <<HEADER;
+print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
* unicode_category_table.h
@@ -188,18 +325,117 @@ typedef struct
uint8 category; /* General Category */
} pg_category_range;
-/* table of Unicode codepoint ranges and their categories */
-static const pg_category_range unicode_categories[$num_ranges] =
+typedef struct
{
-HEADER
+ uint32 first; /* Unicode codepoint */
+ uint32 last; /* Unicode codepoint */
+} pg_unicode_range;
-my $firsttime = 1;
-foreach my $range (@category_ranges) {
- printf $OT ",\n" unless $firsttime;
- $firsttime = 0;
+EOS
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges and their categories */
+static const pg_category_range unicode_categories[$num_category_ranges] =
+{
+EOS
- my $category = $categories->{$range->{category}};
+foreach my $range (@category_ranges)
+{
+ my $category = $categories->{ $range->{category} };
die "category missing: $range->{category}" unless $category;
- printf $OT "\t{0x%06x, 0x%06x, %s}", $range->{start}, $range->{end}, $category;
+ printf $OT "\t{0x%06x, 0x%06x, %s},\n", $range->{start}, $range->{end},
+ $category;
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Alphabetic characters */
+static const pg_unicode_range unicode_alphabetic[$num_alphabetic_ranges] =
+{
+EOS
+
+foreach my $range (@alphabetic)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Lowercase characters */
+static const pg_unicode_range unicode_lowercase[$num_lowercase_ranges] =
+{
+EOS
+
+foreach my $range (@lowercase)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Uppercase characters */
+static const pg_unicode_range unicode_uppercase[$num_uppercase_ranges] =
+{
+EOS
+
+foreach my $range (@uppercase)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Case_Ignorable characters */
+static const pg_unicode_range unicode_case_ignorable[$num_case_ignorable_ranges] =
+{
+EOS
+
+foreach my $range (@case_ignorable)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of White_Space characters */
+static const pg_unicode_range unicode_white_space[$num_white_space_ranges] =
+{
+EOS
+
+foreach my $range (@white_space)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Hex_Digit characters */
+static const pg_unicode_range unicode_hex_digit[$num_hex_digit_ranges] =
+{
+EOS
+
+foreach my $range (@hex_digits)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Join_Control characters */
+static const pg_unicode_range unicode_join_control[$num_join_control_ranges] =
+{
+EOS
+
+foreach my $range (@join_control)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
}
-print $OT "\n};\n";
+
+print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index df4f3a4ed1..d7190bb8ca 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_category_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['UnicodeData.txt'], unicode_data['DerivedCoreProperties.txt'], unicode_data['PropList.txt']],
output: ['unicode_category_table.h'],
command: [
perl, files('generate-unicode_category_table.pl'),
diff --git a/src/common/unicode_category.c b/src/common/unicode_category.c
index 668051b461..a37c52e204 100644
--- a/src/common/unicode_category.c
+++ b/src/common/unicode_category.c
@@ -1,6 +1,8 @@
/*-------------------------------------------------------------------------
* unicode_category.c
- * Determine general category of Unicode characters.
+ * Determine general category and character properties of Unicode
+ * characters. Encoding must be UTF8, where we assume that the pg_wchar
+ * representation is a code point.
*
* Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
*
@@ -18,24 +20,82 @@
#include "common/unicode_category.h"
#include "common/unicode_category_table.h"
+/*
+ * Create bitmasks from pg_unicode_category values for efficient comparison of
+ * multiple categories. For instance, PG_U_MN_MASK is a bitmask representing
+ * the general cateogry Mn; and PG_U_M_MASK represents general categories Mn,
+ * Me, and Mc.
+ *
+ * The number of Unicode General Categories should never grow, so a 32-bit
+ * mask is fine.
+ */
+#define PG_U_CATEGORY_MASK(X) ((uint32)(1 << (X)))
+
+#define PG_U_LU_MASK PG_U_CATEGORY_MASK(PG_U_UPPERCASE_LETTER)
+#define PG_U_LL_MASK PG_U_CATEGORY_MASK(PG_U_LOWERCASE_LETTER)
+#define PG_U_LT_MASK PG_U_CATEGORY_MASK(PG_U_TITLECASE_LETTER)
+#define PG_U_LC_MASK (PG_U_LU_MASK|PG_U_LL_MASK|PG_U_LT_MASK)
+#define PG_U_LM_MASK PG_U_CATEGORY_MASK(PG_U_MODIFIER_LETTER)
+#define PG_U_LO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_LETTER)
+#define PG_U_L_MASK (PG_U_LU_MASK|PG_U_LL_MASK|PG_U_LT_MASK|PG_U_LM_MASK|\
+ PG_U_LO_MASK)
+#define PG_U_MN_MASK PG_U_CATEGORY_MASK(PG_U_NONSPACING_MARK)
+#define PG_U_ME_MASK PG_U_CATEGORY_MASK(PG_U_ENCLOSING_MARK)
+#define PG_U_MC_MASK PG_U_CATEGORY_MASK(PG_U_SPACING_MARK)
+#define PG_U_M_MASK (PG_U_MN_MASK|PG_U_MC_MASK|PG_U_ME_MASK)
+#define PG_U_ND_MASK PG_U_CATEGORY_MASK(PG_U_DECIMAL_NUMBER)
+#define PG_U_NL_MASK PG_U_CATEGORY_MASK(PG_U_LETTER_NUMBER)
+#define PG_U_NO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_NUMBER)
+#define PG_U_N_MASK (PG_U_ND_MASK|PG_U_NL_MASK|PG_U_NO_MASK)
+#define PG_U_PC_MASK PG_U_CATEGORY_MASK(PG_U_CONNECTOR_PUNCTUATION)
+#define PG_U_PD_MASK PG_U_CATEGORY_MASK(PG_U_DASH_PUNCTUATION)
+#define PG_U_PS_MASK PG_U_CATEGORY_MASK(PG_U_OPEN_PUNCTUATION)
+#define PG_U_PE_MASK PG_U_CATEGORY_MASK(PG_U_CLOSE_PUNCTUATION)
+#define PG_U_PI_MASK PG_U_CATEGORY_MASK(PG_U_INITIAL_PUNCTUATION)
+#define PG_U_PF_MASK PG_U_CATEGORY_MASK(PG_U_FINAL_PUNCTUATION)
+#define PG_U_PO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_PUNCTUATION)
+#define PG_U_P_MASK (PG_U_PC_MASK|PG_U_PD_MASK|PG_U_PS_MASK|PG_U_PE_MASK|\
+ PG_U_PI_MASK|PG_U_PF_MASK|PG_U_PO_MASK)
+#define PG_U_SM_MASK PG_U_CATEGORY_MASK(PG_U_MATH_SYMBOL)
+#define PG_U_SC_MASK PG_U_CATEGORY_MASK(PG_U_CURRENCY_SYMBOL)
+#define PG_U_SK_MASK PG_U_CATEGORY_MASK(PG_U_MODIFIER_SYMBOL)
+#define PG_U_SO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_SYMBOL)
+#define PG_U_S_MASK (PG_U_SM_MASK|PG_U_SC_MASK|PG_U_SK_MASK|PG_U_SO_MASK)
+#define PG_U_ZS_MASK PG_U_CATEGORY_MASK(PG_U_SPACE_SEPARATOR)
+#define PG_U_ZL_MASK PG_U_CATEGORY_MASK(PG_U_LINE_SEPARATOR)
+#define PG_U_ZP_MASK PG_U_CATEGORY_MASK(PG_U_PARAGRAPH_SEPARATOR)
+#define PG_U_Z_MASK (PG_U_ZS_MASK|PG_U_ZL_MASK|PG_U_ZP_MASK)
+#define PG_U_CC_MASK PG_U_CATEGORY_MASK(PG_U_CONTROL)
+#define PG_U_CF_MASK PG_U_CATEGORY_MASK(PG_U_FORMAT)
+#define PG_U_CS_MASK PG_U_CATEGORY_MASK(PG_U_SURROGATE)
+#define PG_U_CO_MASK PG_U_CATEGORY_MASK(PG_U_PRIVATE_USE)
+#define PG_U_CN_MASK PG_U_CATEGORY_MASK(PG_U_UNASSIGNED)
+#define PG_U_C_MASK (PG_U_CC_MASK|PG_U_CF_MASK|PG_U_CS_MASK|PG_U_CO_MASK|\
+ PG_U_CN_MASK)
+
+#define PG_U_CHARACTER_TAB 0x09
+
+static bool range_search(const pg_unicode_range * tbl, size_t size,
+ pg_wchar code);
+
/*
* Unicode general category for the given codepoint.
*/
pg_unicode_category
-unicode_category(pg_wchar ucs)
+unicode_category(pg_wchar code)
{
int min = 0;
int mid;
int max = lengthof(unicode_categories) - 1;
- Assert(ucs <= 0x10ffff);
+ Assert(code <= 0x10ffff);
while (max >= min)
{
mid = (min + max) / 2;
- if (ucs > unicode_categories[mid].last)
+ if (code > unicode_categories[mid].last)
min = mid + 1;
- else if (ucs < unicode_categories[mid].first)
+ else if (code < unicode_categories[mid].first)
max = mid - 1;
else
return unicode_categories[mid].category;
@@ -44,6 +104,198 @@ unicode_category(pg_wchar ucs)
return PG_U_UNASSIGNED;
}
+bool
+pg_u_prop_alphabetic(pg_wchar code)
+{
+ return range_search(unicode_alphabetic,
+ lengthof(unicode_alphabetic),
+ code);
+}
+
+bool
+pg_u_prop_lowercase(pg_wchar code)
+{
+ return range_search(unicode_lowercase,
+ lengthof(unicode_lowercase),
+ code);
+}
+
+bool
+pg_u_prop_uppercase(pg_wchar code)
+{
+ return range_search(unicode_uppercase,
+ lengthof(unicode_uppercase),
+ code);
+}
+
+bool
+pg_u_prop_cased(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return category_mask & PG_U_LT_MASK ||
+ pg_u_prop_lowercase(code) ||
+ pg_u_prop_uppercase(code);
+}
+
+bool
+pg_u_prop_case_ignorable(pg_wchar code)
+{
+ return range_search(unicode_case_ignorable,
+ lengthof(unicode_case_ignorable),
+ code);
+}
+
+bool
+pg_u_prop_white_space(pg_wchar code)
+{
+ return range_search(unicode_white_space,
+ lengthof(unicode_white_space),
+ code);
+}
+
+bool
+pg_u_prop_hex_digit(pg_wchar code)
+{
+ return range_search(unicode_hex_digit,
+ lengthof(unicode_hex_digit),
+ code);
+}
+
+bool
+pg_u_prop_join_control(pg_wchar code)
+{
+ return range_search(unicode_join_control,
+ lengthof(unicode_join_control),
+ code);
+}
+
+/*
+ * The following functions implement the Compatibility Properties described
+ * at: http://www.unicode.org/reports/tr18/#Compatibility_Properties
+ *
+ * If 'posix' is true, implements the "POSIX Compatible" variant, otherwise
+ * the "Standard" variant.
+ */
+
+bool
+pg_u_isdigit(pg_wchar code, bool posix)
+{
+ if (posix)
+ return ('0' <= code && code <= '9');
+ else
+ return unicode_category(code) == PG_U_DECIMAL_NUMBER;
+}
+
+bool
+pg_u_isalpha(pg_wchar code)
+{
+ return pg_u_prop_alphabetic(code);
+}
+
+bool
+pg_u_isalnum(pg_wchar code, bool posix)
+{
+ return pg_u_isalpha(code) || pg_u_isdigit(code, posix);
+}
+
+bool
+pg_u_isword(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return
+ category_mask & (PG_U_M_MASK | PG_U_ND_MASK | PG_U_PC_MASK) ||
+ pg_u_isalpha(code) ||
+ pg_u_prop_join_control(code);
+}
+
+bool
+pg_u_isupper(pg_wchar code)
+{
+ return pg_u_prop_uppercase(code);
+}
+
+bool
+pg_u_islower(pg_wchar code)
+{
+ return pg_u_prop_lowercase(code);
+}
+
+bool
+pg_u_isblank(pg_wchar code)
+{
+ return code == PG_U_CHARACTER_TAB ||
+ unicode_category(code) == PG_U_SPACE_SEPARATOR;
+}
+
+bool
+pg_u_iscntrl(pg_wchar code)
+{
+ return unicode_category(code) == PG_U_CONTROL;
+}
+
+bool
+pg_u_isgraph(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ if (category_mask & (PG_U_CC_MASK | PG_U_CS_MASK | PG_U_CN_MASK) ||
+ pg_u_isspace(code))
+ return false;
+ return true;
+}
+
+bool
+pg_u_isprint(pg_wchar code)
+{
+ pg_unicode_category category = unicode_category(code);
+
+ if (category == PG_U_CONTROL)
+ return false;
+
+ return pg_u_isgraph(code) || pg_u_isblank(code);
+}
+
+bool
+pg_u_ispunct(pg_wchar code, bool posix)
+{
+ uint32 category_mask;
+
+ if (posix)
+ {
+ if (pg_u_isalpha(code))
+ return false;
+
+ category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+ return category_mask & (PG_U_P_MASK | PG_U_S_MASK);
+ }
+ else
+ {
+ category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return category_mask & PG_U_P_MASK;
+ }
+}
+
+bool
+pg_u_isspace(pg_wchar code)
+{
+ return pg_u_prop_white_space(code);
+}
+
+bool
+pg_u_isxdigit(pg_wchar code, bool posix)
+{
+ if (posix)
+ return (('0' <= code && code <= '9') ||
+ ('A' <= code && code <= 'F') ||
+ ('a' <= code && code <= 'f'));
+ else
+ return unicode_category(code) == PG_U_DECIMAL_NUMBER ||
+ pg_u_prop_hex_digit(code);
+}
+
/*
* Description of Unicode general category.
*/
@@ -191,3 +443,30 @@ unicode_category_abbrev(pg_unicode_category category)
Assert(false);
return "??"; /* keep compiler quiet */
}
+
+/*
+ * Binary search to test if given codepoint exists in one of the ranges in the
+ * given table.
+ */
+static bool
+range_search(const pg_unicode_range * tbl, size_t size, pg_wchar code)
+{
+ int min = 0;
+ int mid;
+ int max = size - 1;
+
+ Assert(code <= 0x10ffff);
+
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (code > tbl[mid].last)
+ min = mid + 1;
+ else if (code < tbl[mid].first)
+ max = mid - 1;
+ else
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/include/common/unicode_category.h b/src/include/common/unicode_category.h
index 5bad280615..f185b58900 100644
--- a/src/include/common/unicode_category.h
+++ b/src/include/common/unicode_category.h
@@ -62,7 +62,30 @@ typedef enum pg_unicode_category
} pg_unicode_category;
extern pg_unicode_category unicode_category(pg_wchar ucs);
-const char *unicode_category_string(pg_unicode_category category);
-const char *unicode_category_abbrev(pg_unicode_category category);
+extern const char *unicode_category_string(pg_unicode_category category);
+extern const char *unicode_category_abbrev(pg_unicode_category category);
+
+extern bool pg_u_prop_alphabetic(pg_wchar c);
+extern bool pg_u_prop_lowercase(pg_wchar c);
+extern bool pg_u_prop_uppercase(pg_wchar c);
+extern bool pg_u_prop_cased(pg_wchar c);
+extern bool pg_u_prop_case_ignorable(pg_wchar c);
+extern bool pg_u_prop_white_space(pg_wchar c);
+extern bool pg_u_prop_hex_digit(pg_wchar c);
+extern bool pg_u_prop_join_control(pg_wchar c);
+
+extern bool pg_u_isdigit(pg_wchar c, bool posix);
+extern bool pg_u_isalpha(pg_wchar c);
+extern bool pg_u_isalnum(pg_wchar c, bool posix);
+extern bool pg_u_isword(pg_wchar c);
+extern bool pg_u_isupper(pg_wchar c);
+extern bool pg_u_islower(pg_wchar c);
+extern bool pg_u_isblank(pg_wchar c);
+extern bool pg_u_iscntrl(pg_wchar c);
+extern bool pg_u_isgraph(pg_wchar c);
+extern bool pg_u_isprint(pg_wchar c);
+extern bool pg_u_ispunct(pg_wchar c, bool posix);
+extern bool pg_u_isspace(pg_wchar c);
+extern bool pg_u_isxdigit(pg_wchar c, bool posix);
#endif /* UNICODE_CATEGORY_H */
diff --git a/src/include/common/unicode_category_table.h b/src/include/common/unicode_category_table.h
index d7ef996189..3bede82f20 100644
--- a/src/include/common/unicode_category_table.h
+++ b/src/include/common/unicode_category_table.h
@@ -25,6 +25,12 @@ typedef struct
uint8 category; /* General Category */
} pg_category_range;
+typedef struct
+{
+ uint32 first; /* Unicode codepoint */
+ uint32 last; /* Unicode codepoint */
+} pg_unicode_range;
+
/* table of Unicode codepoint ranges and their categories */
static const pg_category_range unicode_categories[3302] =
{
@@ -3329,5 +3335,3027 @@ static const pg_category_range unicode_categories[3302] =
{0x0e0020, 0x0e007f, PG_U_FORMAT},
{0x0e0100, 0x0e01ef, PG_U_NONSPACING_MARK},
{0x0f0000, 0x0ffffd, PG_U_PRIVATE_USE},
- {0x100000, 0x10fffd, PG_U_PRIVATE_USE}
+ {0x100000, 0x10fffd, PG_U_PRIVATE_USE},
+};
+
+/* table of Unicode codepoint ranges of Alphabetic characters */
+static const pg_unicode_range unicode_alphabetic[1141] =
+{
+ {0x000041, 0x00005a},
+ {0x000061, 0x00007a},
+ {0x0000aa, 0x0000aa},
+ {0x0000b5, 0x0000b5},
+ {0x0000ba, 0x0000ba},
+ {0x0000c0, 0x0000d6},
+ {0x0000d8, 0x0000f6},
+ {0x0000f8, 0x0001ba},
+ {0x0001bb, 0x0001bb},
+ {0x0001bc, 0x0001bf},
+ {0x0001c0, 0x0001c3},
+ {0x0001c4, 0x000293},
+ {0x000294, 0x000294},
+ {0x000295, 0x0002af},
+ {0x0002b0, 0x0002c1},
+ {0x0002c6, 0x0002d1},
+ {0x0002e0, 0x0002e4},
+ {0x0002ec, 0x0002ec},
+ {0x0002ee, 0x0002ee},
+ {0x000345, 0x000345},
+ {0x000370, 0x000373},
+ {0x000374, 0x000374},
+ {0x000376, 0x000377},
+ {0x00037a, 0x00037a},
+ {0x00037b, 0x00037d},
+ {0x00037f, 0x00037f},
+ {0x000386, 0x000386},
+ {0x000388, 0x00038a},
+ {0x00038c, 0x00038c},
+ {0x00038e, 0x0003a1},
+ {0x0003a3, 0x0003f5},
+ {0x0003f7, 0x000481},
+ {0x00048a, 0x00052f},
+ {0x000531, 0x000556},
+ {0x000559, 0x000559},
+ {0x000560, 0x000588},
+ {0x0005b0, 0x0005bd},
+ {0x0005bf, 0x0005bf},
+ {0x0005c1, 0x0005c2},
+ {0x0005c4, 0x0005c5},
+ {0x0005c7, 0x0005c7},
+ {0x0005d0, 0x0005ea},
+ {0x0005ef, 0x0005f2},
+ {0x000610, 0x00061a},
+ {0x000620, 0x00063f},
+ {0x000640, 0x000640},
+ {0x000641, 0x00064a},
+ {0x00064b, 0x000657},
+ {0x000659, 0x00065f},
+ {0x00066e, 0x00066f},
+ {0x000670, 0x000670},
+ {0x000671, 0x0006d3},
+ {0x0006d5, 0x0006d5},
+ {0x0006d6, 0x0006dc},
+ {0x0006e1, 0x0006e4},
+ {0x0006e5, 0x0006e6},
+ {0x0006e7, 0x0006e8},
+ {0x0006ed, 0x0006ed},
+ {0x0006ee, 0x0006ef},
+ {0x0006fa, 0x0006fc},
+ {0x0006ff, 0x0006ff},
+ {0x000710, 0x000710},
+ {0x000711, 0x000711},
+ {0x000712, 0x00072f},
+ {0x000730, 0x00073f},
+ {0x00074d, 0x0007a5},
+ {0x0007a6, 0x0007b0},
+ {0x0007b1, 0x0007b1},
+ {0x0007ca, 0x0007ea},
+ {0x0007f4, 0x0007f5},
+ {0x0007fa, 0x0007fa},
+ {0x000800, 0x000815},
+ {0x000816, 0x000817},
+ {0x00081a, 0x00081a},
+ {0x00081b, 0x000823},
+ {0x000824, 0x000824},
+ {0x000825, 0x000827},
+ {0x000828, 0x000828},
+ {0x000829, 0x00082c},
+ {0x000840, 0x000858},
+ {0x000860, 0x00086a},
+ {0x000870, 0x000887},
+ {0x000889, 0x00088e},
+ {0x0008a0, 0x0008c8},
+ {0x0008c9, 0x0008c9},
+ {0x0008d4, 0x0008df},
+ {0x0008e3, 0x0008e9},
+ {0x0008f0, 0x000902},
+ {0x000903, 0x000903},
+ {0x000904, 0x000939},
+ {0x00093a, 0x00093a},
+ {0x00093b, 0x00093b},
+ {0x00093d, 0x00093d},
+ {0x00093e, 0x000940},
+ {0x000941, 0x000948},
+ {0x000949, 0x00094c},
+ {0x00094e, 0x00094f},
+ {0x000950, 0x000950},
+ {0x000955, 0x000957},
+ {0x000958, 0x000961},
+ {0x000962, 0x000963},
+ {0x000971, 0x000971},
+ {0x000972, 0x000980},
+ {0x000981, 0x000981},
+ {0x000982, 0x000983},
+ {0x000985, 0x00098c},
+ {0x00098f, 0x000990},
+ {0x000993, 0x0009a8},
+ {0x0009aa, 0x0009b0},
+ {0x0009b2, 0x0009b2},
+ {0x0009b6, 0x0009b9},
+ {0x0009bd, 0x0009bd},
+ {0x0009be, 0x0009c0},
+ {0x0009c1, 0x0009c4},
+ {0x0009c7, 0x0009c8},
+ {0x0009cb, 0x0009cc},
+ {0x0009ce, 0x0009ce},
+ {0x0009d7, 0x0009d7},
+ {0x0009dc, 0x0009dd},
+ {0x0009df, 0x0009e1},
+ {0x0009e2, 0x0009e3},
+ {0x0009f0, 0x0009f1},
+ {0x0009fc, 0x0009fc},
+ {0x000a01, 0x000a02},
+ {0x000a03, 0x000a03},
+ {0x000a05, 0x000a0a},
+ {0x000a0f, 0x000a10},
+ {0x000a13, 0x000a28},
+ {0x000a2a, 0x000a30},
+ {0x000a32, 0x000a33},
+ {0x000a35, 0x000a36},
+ {0x000a38, 0x000a39},
+ {0x000a3e, 0x000a40},
+ {0x000a41, 0x000a42},
+ {0x000a47, 0x000a48},
+ {0x000a4b, 0x000a4c},
+ {0x000a51, 0x000a51},
+ {0x000a59, 0x000a5c},
+ {0x000a5e, 0x000a5e},
+ {0x000a70, 0x000a71},
+ {0x000a72, 0x000a74},
+ {0x000a75, 0x000a75},
+ {0x000a81, 0x000a82},
+ {0x000a83, 0x000a83},
+ {0x000a85, 0x000a8d},
+ {0x000a8f, 0x000a91},
+ {0x000a93, 0x000aa8},
+ {0x000aaa, 0x000ab0},
+ {0x000ab2, 0x000ab3},
+ {0x000ab5, 0x000ab9},
+ {0x000abd, 0x000abd},
+ {0x000abe, 0x000ac0},
+ {0x000ac1, 0x000ac5},
+ {0x000ac7, 0x000ac8},
+ {0x000ac9, 0x000ac9},
+ {0x000acb, 0x000acc},
+ {0x000ad0, 0x000ad0},
+ {0x000ae0, 0x000ae1},
+ {0x000ae2, 0x000ae3},
+ {0x000af9, 0x000af9},
+ {0x000afa, 0x000afc},
+ {0x000b01, 0x000b01},
+ {0x000b02, 0x000b03},
+ {0x000b05, 0x000b0c},
+ {0x000b0f, 0x000b10},
+ {0x000b13, 0x000b28},
+ {0x000b2a, 0x000b30},
+ {0x000b32, 0x000b33},
+ {0x000b35, 0x000b39},
+ {0x000b3d, 0x000b3d},
+ {0x000b3e, 0x000b3e},
+ {0x000b3f, 0x000b3f},
+ {0x000b40, 0x000b40},
+ {0x000b41, 0x000b44},
+ {0x000b47, 0x000b48},
+ {0x000b4b, 0x000b4c},
+ {0x000b56, 0x000b56},
+ {0x000b57, 0x000b57},
+ {0x000b5c, 0x000b5d},
+ {0x000b5f, 0x000b61},
+ {0x000b62, 0x000b63},
+ {0x000b71, 0x000b71},
+ {0x000b82, 0x000b82},
+ {0x000b83, 0x000b83},
+ {0x000b85, 0x000b8a},
+ {0x000b8e, 0x000b90},
+ {0x000b92, 0x000b95},
+ {0x000b99, 0x000b9a},
+ {0x000b9c, 0x000b9c},
+ {0x000b9e, 0x000b9f},
+ {0x000ba3, 0x000ba4},
+ {0x000ba8, 0x000baa},
+ {0x000bae, 0x000bb9},
+ {0x000bbe, 0x000bbf},
+ {0x000bc0, 0x000bc0},
+ {0x000bc1, 0x000bc2},
+ {0x000bc6, 0x000bc8},
+ {0x000bca, 0x000bcc},
+ {0x000bd0, 0x000bd0},
+ {0x000bd7, 0x000bd7},
+ {0x000c00, 0x000c00},
+ {0x000c01, 0x000c03},
+ {0x000c04, 0x000c04},
+ {0x000c05, 0x000c0c},
+ {0x000c0e, 0x000c10},
+ {0x000c12, 0x000c28},
+ {0x000c2a, 0x000c39},
+ {0x000c3d, 0x000c3d},
+ {0x000c3e, 0x000c40},
+ {0x000c41, 0x000c44},
+ {0x000c46, 0x000c48},
+ {0x000c4a, 0x000c4c},
+ {0x000c55, 0x000c56},
+ {0x000c58, 0x000c5a},
+ {0x000c5d, 0x000c5d},
+ {0x000c60, 0x000c61},
+ {0x000c62, 0x000c63},
+ {0x000c80, 0x000c80},
+ {0x000c81, 0x000c81},
+ {0x000c82, 0x000c83},
+ {0x000c85, 0x000c8c},
+ {0x000c8e, 0x000c90},
+ {0x000c92, 0x000ca8},
+ {0x000caa, 0x000cb3},
+ {0x000cb5, 0x000cb9},
+ {0x000cbd, 0x000cbd},
+ {0x000cbe, 0x000cbe},
+ {0x000cbf, 0x000cbf},
+ {0x000cc0, 0x000cc4},
+ {0x000cc6, 0x000cc6},
+ {0x000cc7, 0x000cc8},
+ {0x000cca, 0x000ccb},
+ {0x000ccc, 0x000ccc},
+ {0x000cd5, 0x000cd6},
+ {0x000cdd, 0x000cde},
+ {0x000ce0, 0x000ce1},
+ {0x000ce2, 0x000ce3},
+ {0x000cf1, 0x000cf2},
+ {0x000cf3, 0x000cf3},
+ {0x000d00, 0x000d01},
+ {0x000d02, 0x000d03},
+ {0x000d04, 0x000d0c},
+ {0x000d0e, 0x000d10},
+ {0x000d12, 0x000d3a},
+ {0x000d3d, 0x000d3d},
+ {0x000d3e, 0x000d40},
+ {0x000d41, 0x000d44},
+ {0x000d46, 0x000d48},
+ {0x000d4a, 0x000d4c},
+ {0x000d4e, 0x000d4e},
+ {0x000d54, 0x000d56},
+ {0x000d57, 0x000d57},
+ {0x000d5f, 0x000d61},
+ {0x000d62, 0x000d63},
+ {0x000d7a, 0x000d7f},
+ {0x000d81, 0x000d81},
+ {0x000d82, 0x000d83},
+ {0x000d85, 0x000d96},
+ {0x000d9a, 0x000db1},
+ {0x000db3, 0x000dbb},
+ {0x000dbd, 0x000dbd},
+ {0x000dc0, 0x000dc6},
+ {0x000dcf, 0x000dd1},
+ {0x000dd2, 0x000dd4},
+ {0x000dd6, 0x000dd6},
+ {0x000dd8, 0x000ddf},
+ {0x000df2, 0x000df3},
+ {0x000e01, 0x000e30},
+ {0x000e31, 0x000e31},
+ {0x000e32, 0x000e33},
+ {0x000e34, 0x000e3a},
+ {0x000e40, 0x000e45},
+ {0x000e46, 0x000e46},
+ {0x000e4d, 0x000e4d},
+ {0x000e81, 0x000e82},
+ {0x000e84, 0x000e84},
+ {0x000e86, 0x000e8a},
+ {0x000e8c, 0x000ea3},
+ {0x000ea5, 0x000ea5},
+ {0x000ea7, 0x000eb0},
+ {0x000eb1, 0x000eb1},
+ {0x000eb2, 0x000eb3},
+ {0x000eb4, 0x000eb9},
+ {0x000ebb, 0x000ebc},
+ {0x000ebd, 0x000ebd},
+ {0x000ec0, 0x000ec4},
+ {0x000ec6, 0x000ec6},
+ {0x000ecd, 0x000ecd},
+ {0x000edc, 0x000edf},
+ {0x000f00, 0x000f00},
+ {0x000f40, 0x000f47},
+ {0x000f49, 0x000f6c},
+ {0x000f71, 0x000f7e},
+ {0x000f7f, 0x000f7f},
+ {0x000f80, 0x000f83},
+ {0x000f88, 0x000f8c},
+ {0x000f8d, 0x000f97},
+ {0x000f99, 0x000fbc},
+ {0x001000, 0x00102a},
+ {0x00102b, 0x00102c},
+ {0x00102d, 0x001030},
+ {0x001031, 0x001031},
+ {0x001032, 0x001036},
+ {0x001038, 0x001038},
+ {0x00103b, 0x00103c},
+ {0x00103d, 0x00103e},
+ {0x00103f, 0x00103f},
+ {0x001050, 0x001055},
+ {0x001056, 0x001057},
+ {0x001058, 0x001059},
+ {0x00105a, 0x00105d},
+ {0x00105e, 0x001060},
+ {0x001061, 0x001061},
+ {0x001062, 0x001064},
+ {0x001065, 0x001066},
+ {0x001067, 0x00106d},
+ {0x00106e, 0x001070},
+ {0x001071, 0x001074},
+ {0x001075, 0x001081},
+ {0x001082, 0x001082},
+ {0x001083, 0x001084},
+ {0x001085, 0x001086},
+ {0x001087, 0x00108c},
+ {0x00108d, 0x00108d},
+ {0x00108e, 0x00108e},
+ {0x00108f, 0x00108f},
+ {0x00109a, 0x00109c},
+ {0x00109d, 0x00109d},
+ {0x0010a0, 0x0010c5},
+ {0x0010c7, 0x0010c7},
+ {0x0010cd, 0x0010cd},
+ {0x0010d0, 0x0010fa},
+ {0x0010fc, 0x0010fc},
+ {0x0010fd, 0x0010ff},
+ {0x001100, 0x001248},
+ {0x00124a, 0x00124d},
+ {0x001250, 0x001256},
+ {0x001258, 0x001258},
+ {0x00125a, 0x00125d},
+ {0x001260, 0x001288},
+ {0x00128a, 0x00128d},
+ {0x001290, 0x0012b0},
+ {0x0012b2, 0x0012b5},
+ {0x0012b8, 0x0012be},
+ {0x0012c0, 0x0012c0},
+ {0x0012c2, 0x0012c5},
+ {0x0012c8, 0x0012d6},
+ {0x0012d8, 0x001310},
+ {0x001312, 0x001315},
+ {0x001318, 0x00135a},
+ {0x001380, 0x00138f},
+ {0x0013a0, 0x0013f5},
+ {0x0013f8, 0x0013fd},
+ {0x001401, 0x00166c},
+ {0x00166f, 0x00167f},
+ {0x001681, 0x00169a},
+ {0x0016a0, 0x0016ea},
+ {0x0016ee, 0x0016f0},
+ {0x0016f1, 0x0016f8},
+ {0x001700, 0x001711},
+ {0x001712, 0x001713},
+ {0x00171f, 0x001731},
+ {0x001732, 0x001733},
+ {0x001740, 0x001751},
+ {0x001752, 0x001753},
+ {0x001760, 0x00176c},
+ {0x00176e, 0x001770},
+ {0x001772, 0x001773},
+ {0x001780, 0x0017b3},
+ {0x0017b6, 0x0017b6},
+ {0x0017b7, 0x0017bd},
+ {0x0017be, 0x0017c5},
+ {0x0017c6, 0x0017c6},
+ {0x0017c7, 0x0017c8},
+ {0x0017d7, 0x0017d7},
+ {0x0017dc, 0x0017dc},
+ {0x001820, 0x001842},
+ {0x001843, 0x001843},
+ {0x001844, 0x001878},
+ {0x001880, 0x001884},
+ {0x001885, 0x001886},
+ {0x001887, 0x0018a8},
+ {0x0018a9, 0x0018a9},
+ {0x0018aa, 0x0018aa},
+ {0x0018b0, 0x0018f5},
+ {0x001900, 0x00191e},
+ {0x001920, 0x001922},
+ {0x001923, 0x001926},
+ {0x001927, 0x001928},
+ {0x001929, 0x00192b},
+ {0x001930, 0x001931},
+ {0x001932, 0x001932},
+ {0x001933, 0x001938},
+ {0x001950, 0x00196d},
+ {0x001970, 0x001974},
+ {0x001980, 0x0019ab},
+ {0x0019b0, 0x0019c9},
+ {0x001a00, 0x001a16},
+ {0x001a17, 0x001a18},
+ {0x001a19, 0x001a1a},
+ {0x001a1b, 0x001a1b},
+ {0x001a20, 0x001a54},
+ {0x001a55, 0x001a55},
+ {0x001a56, 0x001a56},
+ {0x001a57, 0x001a57},
+ {0x001a58, 0x001a5e},
+ {0x001a61, 0x001a61},
+ {0x001a62, 0x001a62},
+ {0x001a63, 0x001a64},
+ {0x001a65, 0x001a6c},
+ {0x001a6d, 0x001a72},
+ {0x001a73, 0x001a74},
+ {0x001aa7, 0x001aa7},
+ {0x001abf, 0x001ac0},
+ {0x001acc, 0x001ace},
+ {0x001b00, 0x001b03},
+ {0x001b04, 0x001b04},
+ {0x001b05, 0x001b33},
+ {0x001b35, 0x001b35},
+ {0x001b36, 0x001b3a},
+ {0x001b3b, 0x001b3b},
+ {0x001b3c, 0x001b3c},
+ {0x001b3d, 0x001b41},
+ {0x001b42, 0x001b42},
+ {0x001b43, 0x001b43},
+ {0x001b45, 0x001b4c},
+ {0x001b80, 0x001b81},
+ {0x001b82, 0x001b82},
+ {0x001b83, 0x001ba0},
+ {0x001ba1, 0x001ba1},
+ {0x001ba2, 0x001ba5},
+ {0x001ba6, 0x001ba7},
+ {0x001ba8, 0x001ba9},
+ {0x001bac, 0x001bad},
+ {0x001bae, 0x001baf},
+ {0x001bba, 0x001be5},
+ {0x001be7, 0x001be7},
+ {0x001be8, 0x001be9},
+ {0x001bea, 0x001bec},
+ {0x001bed, 0x001bed},
+ {0x001bee, 0x001bee},
+ {0x001bef, 0x001bf1},
+ {0x001c00, 0x001c23},
+ {0x001c24, 0x001c2b},
+ {0x001c2c, 0x001c33},
+ {0x001c34, 0x001c35},
+ {0x001c36, 0x001c36},
+ {0x001c4d, 0x001c4f},
+ {0x001c5a, 0x001c77},
+ {0x001c78, 0x001c7d},
+ {0x001c80, 0x001c88},
+ {0x001c90, 0x001cba},
+ {0x001cbd, 0x001cbf},
+ {0x001ce9, 0x001cec},
+ {0x001cee, 0x001cf3},
+ {0x001cf5, 0x001cf6},
+ {0x001cfa, 0x001cfa},
+ {0x001d00, 0x001d2b},
+ {0x001d2c, 0x001d6a},
+ {0x001d6b, 0x001d77},
+ {0x001d78, 0x001d78},
+ {0x001d79, 0x001d9a},
+ {0x001d9b, 0x001dbf},
+ {0x001de7, 0x001df4},
+ {0x001e00, 0x001f15},
+ {0x001f18, 0x001f1d},
+ {0x001f20, 0x001f45},
+ {0x001f48, 0x001f4d},
+ {0x001f50, 0x001f57},
+ {0x001f59, 0x001f59},
+ {0x001f5b, 0x001f5b},
+ {0x001f5d, 0x001f5d},
+ {0x001f5f, 0x001f7d},
+ {0x001f80, 0x001fb4},
+ {0x001fb6, 0x001fbc},
+ {0x001fbe, 0x001fbe},
+ {0x001fc2, 0x001fc4},
+ {0x001fc6, 0x001fcc},
+ {0x001fd0, 0x001fd3},
+ {0x001fd6, 0x001fdb},
+ {0x001fe0, 0x001fec},
+ {0x001ff2, 0x001ff4},
+ {0x001ff6, 0x001ffc},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x002102, 0x002102},
+ {0x002107, 0x002107},
+ {0x00210a, 0x002113},
+ {0x002115, 0x002115},
+ {0x002119, 0x00211d},
+ {0x002124, 0x002124},
+ {0x002126, 0x002126},
+ {0x002128, 0x002128},
+ {0x00212a, 0x00212d},
+ {0x00212f, 0x002134},
+ {0x002135, 0x002138},
+ {0x002139, 0x002139},
+ {0x00213c, 0x00213f},
+ {0x002145, 0x002149},
+ {0x00214e, 0x00214e},
+ {0x002160, 0x002182},
+ {0x002183, 0x002184},
+ {0x002185, 0x002188},
+ {0x0024b6, 0x0024e9},
+ {0x002c00, 0x002c7b},
+ {0x002c7c, 0x002c7d},
+ {0x002c7e, 0x002ce4},
+ {0x002ceb, 0x002cee},
+ {0x002cf2, 0x002cf3},
+ {0x002d00, 0x002d25},
+ {0x002d27, 0x002d27},
+ {0x002d2d, 0x002d2d},
+ {0x002d30, 0x002d67},
+ {0x002d6f, 0x002d6f},
+ {0x002d80, 0x002d96},
+ {0x002da0, 0x002da6},
+ {0x002da8, 0x002dae},
+ {0x002db0, 0x002db6},
+ {0x002db8, 0x002dbe},
+ {0x002dc0, 0x002dc6},
+ {0x002dc8, 0x002dce},
+ {0x002dd0, 0x002dd6},
+ {0x002dd8, 0x002dde},
+ {0x002de0, 0x002dff},
+ {0x002e2f, 0x002e2f},
+ {0x003005, 0x003005},
+ {0x003006, 0x003006},
+ {0x003007, 0x003007},
+ {0x003021, 0x003029},
+ {0x003031, 0x003035},
+ {0x003038, 0x00303a},
+ {0x00303b, 0x00303b},
+ {0x00303c, 0x00303c},
+ {0x003041, 0x003096},
+ {0x00309d, 0x00309e},
+ {0x00309f, 0x00309f},
+ {0x0030a1, 0x0030fa},
+ {0x0030fc, 0x0030fe},
+ {0x0030ff, 0x0030ff},
+ {0x003105, 0x00312f},
+ {0x003131, 0x00318e},
+ {0x0031a0, 0x0031bf},
+ {0x0031f0, 0x0031ff},
+ {0x003400, 0x004dbf},
+ {0x004e00, 0x00a014},
+ {0x00a015, 0x00a015},
+ {0x00a016, 0x00a48c},
+ {0x00a4d0, 0x00a4f7},
+ {0x00a4f8, 0x00a4fd},
+ {0x00a500, 0x00a60b},
+ {0x00a60c, 0x00a60c},
+ {0x00a610, 0x00a61f},
+ {0x00a62a, 0x00a62b},
+ {0x00a640, 0x00a66d},
+ {0x00a66e, 0x00a66e},
+ {0x00a674, 0x00a67b},
+ {0x00a67f, 0x00a67f},
+ {0x00a680, 0x00a69b},
+ {0x00a69c, 0x00a69d},
+ {0x00a69e, 0x00a69f},
+ {0x00a6a0, 0x00a6e5},
+ {0x00a6e6, 0x00a6ef},
+ {0x00a717, 0x00a71f},
+ {0x00a722, 0x00a76f},
+ {0x00a770, 0x00a770},
+ {0x00a771, 0x00a787},
+ {0x00a788, 0x00a788},
+ {0x00a78b, 0x00a78e},
+ {0x00a78f, 0x00a78f},
+ {0x00a790, 0x00a7ca},
+ {0x00a7d0, 0x00a7d1},
+ {0x00a7d3, 0x00a7d3},
+ {0x00a7d5, 0x00a7d9},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f5, 0x00a7f6},
+ {0x00a7f7, 0x00a7f7},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a7fa, 0x00a7fa},
+ {0x00a7fb, 0x00a801},
+ {0x00a802, 0x00a802},
+ {0x00a803, 0x00a805},
+ {0x00a807, 0x00a80a},
+ {0x00a80b, 0x00a80b},
+ {0x00a80c, 0x00a822},
+ {0x00a823, 0x00a824},
+ {0x00a825, 0x00a826},
+ {0x00a827, 0x00a827},
+ {0x00a840, 0x00a873},
+ {0x00a880, 0x00a881},
+ {0x00a882, 0x00a8b3},
+ {0x00a8b4, 0x00a8c3},
+ {0x00a8c5, 0x00a8c5},
+ {0x00a8f2, 0x00a8f7},
+ {0x00a8fb, 0x00a8fb},
+ {0x00a8fd, 0x00a8fe},
+ {0x00a8ff, 0x00a8ff},
+ {0x00a90a, 0x00a925},
+ {0x00a926, 0x00a92a},
+ {0x00a930, 0x00a946},
+ {0x00a947, 0x00a951},
+ {0x00a952, 0x00a952},
+ {0x00a960, 0x00a97c},
+ {0x00a980, 0x00a982},
+ {0x00a983, 0x00a983},
+ {0x00a984, 0x00a9b2},
+ {0x00a9b4, 0x00a9b5},
+ {0x00a9b6, 0x00a9b9},
+ {0x00a9ba, 0x00a9bb},
+ {0x00a9bc, 0x00a9bd},
+ {0x00a9be, 0x00a9bf},
+ {0x00a9cf, 0x00a9cf},
+ {0x00a9e0, 0x00a9e4},
+ {0x00a9e5, 0x00a9e5},
+ {0x00a9e6, 0x00a9e6},
+ {0x00a9e7, 0x00a9ef},
+ {0x00a9fa, 0x00a9fe},
+ {0x00aa00, 0x00aa28},
+ {0x00aa29, 0x00aa2e},
+ {0x00aa2f, 0x00aa30},
+ {0x00aa31, 0x00aa32},
+ {0x00aa33, 0x00aa34},
+ {0x00aa35, 0x00aa36},
+ {0x00aa40, 0x00aa42},
+ {0x00aa43, 0x00aa43},
+ {0x00aa44, 0x00aa4b},
+ {0x00aa4c, 0x00aa4c},
+ {0x00aa4d, 0x00aa4d},
+ {0x00aa60, 0x00aa6f},
+ {0x00aa70, 0x00aa70},
+ {0x00aa71, 0x00aa76},
+ {0x00aa7a, 0x00aa7a},
+ {0x00aa7b, 0x00aa7b},
+ {0x00aa7c, 0x00aa7c},
+ {0x00aa7d, 0x00aa7d},
+ {0x00aa7e, 0x00aaaf},
+ {0x00aab0, 0x00aab0},
+ {0x00aab1, 0x00aab1},
+ {0x00aab2, 0x00aab4},
+ {0x00aab5, 0x00aab6},
+ {0x00aab7, 0x00aab8},
+ {0x00aab9, 0x00aabd},
+ {0x00aabe, 0x00aabe},
+ {0x00aac0, 0x00aac0},
+ {0x00aac2, 0x00aac2},
+ {0x00aadb, 0x00aadc},
+ {0x00aadd, 0x00aadd},
+ {0x00aae0, 0x00aaea},
+ {0x00aaeb, 0x00aaeb},
+ {0x00aaec, 0x00aaed},
+ {0x00aaee, 0x00aaef},
+ {0x00aaf2, 0x00aaf2},
+ {0x00aaf3, 0x00aaf4},
+ {0x00aaf5, 0x00aaf5},
+ {0x00ab01, 0x00ab06},
+ {0x00ab09, 0x00ab0e},
+ {0x00ab11, 0x00ab16},
+ {0x00ab20, 0x00ab26},
+ {0x00ab28, 0x00ab2e},
+ {0x00ab30, 0x00ab5a},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab60, 0x00ab68},
+ {0x00ab69, 0x00ab69},
+ {0x00ab70, 0x00abbf},
+ {0x00abc0, 0x00abe2},
+ {0x00abe3, 0x00abe4},
+ {0x00abe5, 0x00abe5},
+ {0x00abe6, 0x00abe7},
+ {0x00abe8, 0x00abe8},
+ {0x00abe9, 0x00abea},
+ {0x00ac00, 0x00d7a3},
+ {0x00d7b0, 0x00d7c6},
+ {0x00d7cb, 0x00d7fb},
+ {0x00f900, 0x00fa6d},
+ {0x00fa70, 0x00fad9},
+ {0x00fb00, 0x00fb06},
+ {0x00fb13, 0x00fb17},
+ {0x00fb1d, 0x00fb1d},
+ {0x00fb1e, 0x00fb1e},
+ {0x00fb1f, 0x00fb28},
+ {0x00fb2a, 0x00fb36},
+ {0x00fb38, 0x00fb3c},
+ {0x00fb3e, 0x00fb3e},
+ {0x00fb40, 0x00fb41},
+ {0x00fb43, 0x00fb44},
+ {0x00fb46, 0x00fbb1},
+ {0x00fbd3, 0x00fd3d},
+ {0x00fd50, 0x00fd8f},
+ {0x00fd92, 0x00fdc7},
+ {0x00fdf0, 0x00fdfb},
+ {0x00fe70, 0x00fe74},
+ {0x00fe76, 0x00fefc},
+ {0x00ff21, 0x00ff3a},
+ {0x00ff41, 0x00ff5a},
+ {0x00ff66, 0x00ff6f},
+ {0x00ff70, 0x00ff70},
+ {0x00ff71, 0x00ff9d},
+ {0x00ff9e, 0x00ff9f},
+ {0x00ffa0, 0x00ffbe},
+ {0x00ffc2, 0x00ffc7},
+ {0x00ffca, 0x00ffcf},
+ {0x00ffd2, 0x00ffd7},
+ {0x00ffda, 0x00ffdc},
+ {0x010000, 0x01000b},
+ {0x01000d, 0x010026},
+ {0x010028, 0x01003a},
+ {0x01003c, 0x01003d},
+ {0x01003f, 0x01004d},
+ {0x010050, 0x01005d},
+ {0x010080, 0x0100fa},
+ {0x010140, 0x010174},
+ {0x010280, 0x01029c},
+ {0x0102a0, 0x0102d0},
+ {0x010300, 0x01031f},
+ {0x01032d, 0x010340},
+ {0x010341, 0x010341},
+ {0x010342, 0x010349},
+ {0x01034a, 0x01034a},
+ {0x010350, 0x010375},
+ {0x010376, 0x01037a},
+ {0x010380, 0x01039d},
+ {0x0103a0, 0x0103c3},
+ {0x0103c8, 0x0103cf},
+ {0x0103d1, 0x0103d5},
+ {0x010400, 0x01044f},
+ {0x010450, 0x01049d},
+ {0x0104b0, 0x0104d3},
+ {0x0104d8, 0x0104fb},
+ {0x010500, 0x010527},
+ {0x010530, 0x010563},
+ {0x010570, 0x01057a},
+ {0x01057c, 0x01058a},
+ {0x01058c, 0x010592},
+ {0x010594, 0x010595},
+ {0x010597, 0x0105a1},
+ {0x0105a3, 0x0105b1},
+ {0x0105b3, 0x0105b9},
+ {0x0105bb, 0x0105bc},
+ {0x010600, 0x010736},
+ {0x010740, 0x010755},
+ {0x010760, 0x010767},
+ {0x010780, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010800, 0x010805},
+ {0x010808, 0x010808},
+ {0x01080a, 0x010835},
+ {0x010837, 0x010838},
+ {0x01083c, 0x01083c},
+ {0x01083f, 0x010855},
+ {0x010860, 0x010876},
+ {0x010880, 0x01089e},
+ {0x0108e0, 0x0108f2},
+ {0x0108f4, 0x0108f5},
+ {0x010900, 0x010915},
+ {0x010920, 0x010939},
+ {0x010980, 0x0109b7},
+ {0x0109be, 0x0109bf},
+ {0x010a00, 0x010a00},
+ {0x010a01, 0x010a03},
+ {0x010a05, 0x010a06},
+ {0x010a0c, 0x010a0f},
+ {0x010a10, 0x010a13},
+ {0x010a15, 0x010a17},
+ {0x010a19, 0x010a35},
+ {0x010a60, 0x010a7c},
+ {0x010a80, 0x010a9c},
+ {0x010ac0, 0x010ac7},
+ {0x010ac9, 0x010ae4},
+ {0x010b00, 0x010b35},
+ {0x010b40, 0x010b55},
+ {0x010b60, 0x010b72},
+ {0x010b80, 0x010b91},
+ {0x010c00, 0x010c48},
+ {0x010c80, 0x010cb2},
+ {0x010cc0, 0x010cf2},
+ {0x010d00, 0x010d23},
+ {0x010d24, 0x010d27},
+ {0x010e80, 0x010ea9},
+ {0x010eab, 0x010eac},
+ {0x010eb0, 0x010eb1},
+ {0x010f00, 0x010f1c},
+ {0x010f27, 0x010f27},
+ {0x010f30, 0x010f45},
+ {0x010f70, 0x010f81},
+ {0x010fb0, 0x010fc4},
+ {0x010fe0, 0x010ff6},
+ {0x011000, 0x011000},
+ {0x011001, 0x011001},
+ {0x011002, 0x011002},
+ {0x011003, 0x011037},
+ {0x011038, 0x011045},
+ {0x011071, 0x011072},
+ {0x011073, 0x011074},
+ {0x011075, 0x011075},
+ {0x011080, 0x011081},
+ {0x011082, 0x011082},
+ {0x011083, 0x0110af},
+ {0x0110b0, 0x0110b2},
+ {0x0110b3, 0x0110b6},
+ {0x0110b7, 0x0110b8},
+ {0x0110c2, 0x0110c2},
+ {0x0110d0, 0x0110e8},
+ {0x011100, 0x011102},
+ {0x011103, 0x011126},
+ {0x011127, 0x01112b},
+ {0x01112c, 0x01112c},
+ {0x01112d, 0x011132},
+ {0x011144, 0x011144},
+ {0x011145, 0x011146},
+ {0x011147, 0x011147},
+ {0x011150, 0x011172},
+ {0x011176, 0x011176},
+ {0x011180, 0x011181},
+ {0x011182, 0x011182},
+ {0x011183, 0x0111b2},
+ {0x0111b3, 0x0111b5},
+ {0x0111b6, 0x0111be},
+ {0x0111bf, 0x0111bf},
+ {0x0111c1, 0x0111c4},
+ {0x0111ce, 0x0111ce},
+ {0x0111cf, 0x0111cf},
+ {0x0111da, 0x0111da},
+ {0x0111dc, 0x0111dc},
+ {0x011200, 0x011211},
+ {0x011213, 0x01122b},
+ {0x01122c, 0x01122e},
+ {0x01122f, 0x011231},
+ {0x011232, 0x011233},
+ {0x011234, 0x011234},
+ {0x011237, 0x011237},
+ {0x01123e, 0x01123e},
+ {0x01123f, 0x011240},
+ {0x011241, 0x011241},
+ {0x011280, 0x011286},
+ {0x011288, 0x011288},
+ {0x01128a, 0x01128d},
+ {0x01128f, 0x01129d},
+ {0x01129f, 0x0112a8},
+ {0x0112b0, 0x0112de},
+ {0x0112df, 0x0112df},
+ {0x0112e0, 0x0112e2},
+ {0x0112e3, 0x0112e8},
+ {0x011300, 0x011301},
+ {0x011302, 0x011303},
+ {0x011305, 0x01130c},
+ {0x01130f, 0x011310},
+ {0x011313, 0x011328},
+ {0x01132a, 0x011330},
+ {0x011332, 0x011333},
+ {0x011335, 0x011339},
+ {0x01133d, 0x01133d},
+ {0x01133e, 0x01133f},
+ {0x011340, 0x011340},
+ {0x011341, 0x011344},
+ {0x011347, 0x011348},
+ {0x01134b, 0x01134c},
+ {0x011350, 0x011350},
+ {0x011357, 0x011357},
+ {0x01135d, 0x011361},
+ {0x011362, 0x011363},
+ {0x011400, 0x011434},
+ {0x011435, 0x011437},
+ {0x011438, 0x01143f},
+ {0x011440, 0x011441},
+ {0x011443, 0x011444},
+ {0x011445, 0x011445},
+ {0x011447, 0x01144a},
+ {0x01145f, 0x011461},
+ {0x011480, 0x0114af},
+ {0x0114b0, 0x0114b2},
+ {0x0114b3, 0x0114b8},
+ {0x0114b9, 0x0114b9},
+ {0x0114ba, 0x0114ba},
+ {0x0114bb, 0x0114be},
+ {0x0114bf, 0x0114c0},
+ {0x0114c1, 0x0114c1},
+ {0x0114c4, 0x0114c5},
+ {0x0114c7, 0x0114c7},
+ {0x011580, 0x0115ae},
+ {0x0115af, 0x0115b1},
+ {0x0115b2, 0x0115b5},
+ {0x0115b8, 0x0115bb},
+ {0x0115bc, 0x0115bd},
+ {0x0115be, 0x0115be},
+ {0x0115d8, 0x0115db},
+ {0x0115dc, 0x0115dd},
+ {0x011600, 0x01162f},
+ {0x011630, 0x011632},
+ {0x011633, 0x01163a},
+ {0x01163b, 0x01163c},
+ {0x01163d, 0x01163d},
+ {0x01163e, 0x01163e},
+ {0x011640, 0x011640},
+ {0x011644, 0x011644},
+ {0x011680, 0x0116aa},
+ {0x0116ab, 0x0116ab},
+ {0x0116ac, 0x0116ac},
+ {0x0116ad, 0x0116ad},
+ {0x0116ae, 0x0116af},
+ {0x0116b0, 0x0116b5},
+ {0x0116b8, 0x0116b8},
+ {0x011700, 0x01171a},
+ {0x01171d, 0x01171f},
+ {0x011720, 0x011721},
+ {0x011722, 0x011725},
+ {0x011726, 0x011726},
+ {0x011727, 0x01172a},
+ {0x011740, 0x011746},
+ {0x011800, 0x01182b},
+ {0x01182c, 0x01182e},
+ {0x01182f, 0x011837},
+ {0x011838, 0x011838},
+ {0x0118a0, 0x0118df},
+ {0x0118ff, 0x011906},
+ {0x011909, 0x011909},
+ {0x01190c, 0x011913},
+ {0x011915, 0x011916},
+ {0x011918, 0x01192f},
+ {0x011930, 0x011935},
+ {0x011937, 0x011938},
+ {0x01193b, 0x01193c},
+ {0x01193f, 0x01193f},
+ {0x011940, 0x011940},
+ {0x011941, 0x011941},
+ {0x011942, 0x011942},
+ {0x0119a0, 0x0119a7},
+ {0x0119aa, 0x0119d0},
+ {0x0119d1, 0x0119d3},
+ {0x0119d4, 0x0119d7},
+ {0x0119da, 0x0119db},
+ {0x0119dc, 0x0119df},
+ {0x0119e1, 0x0119e1},
+ {0x0119e3, 0x0119e3},
+ {0x0119e4, 0x0119e4},
+ {0x011a00, 0x011a00},
+ {0x011a01, 0x011a0a},
+ {0x011a0b, 0x011a32},
+ {0x011a35, 0x011a38},
+ {0x011a39, 0x011a39},
+ {0x011a3a, 0x011a3a},
+ {0x011a3b, 0x011a3e},
+ {0x011a50, 0x011a50},
+ {0x011a51, 0x011a56},
+ {0x011a57, 0x011a58},
+ {0x011a59, 0x011a5b},
+ {0x011a5c, 0x011a89},
+ {0x011a8a, 0x011a96},
+ {0x011a97, 0x011a97},
+ {0x011a9d, 0x011a9d},
+ {0x011ab0, 0x011af8},
+ {0x011c00, 0x011c08},
+ {0x011c0a, 0x011c2e},
+ {0x011c2f, 0x011c2f},
+ {0x011c30, 0x011c36},
+ {0x011c38, 0x011c3d},
+ {0x011c3e, 0x011c3e},
+ {0x011c40, 0x011c40},
+ {0x011c72, 0x011c8f},
+ {0x011c92, 0x011ca7},
+ {0x011ca9, 0x011ca9},
+ {0x011caa, 0x011cb0},
+ {0x011cb1, 0x011cb1},
+ {0x011cb2, 0x011cb3},
+ {0x011cb4, 0x011cb4},
+ {0x011cb5, 0x011cb6},
+ {0x011d00, 0x011d06},
+ {0x011d08, 0x011d09},
+ {0x011d0b, 0x011d30},
+ {0x011d31, 0x011d36},
+ {0x011d3a, 0x011d3a},
+ {0x011d3c, 0x011d3d},
+ {0x011d3f, 0x011d41},
+ {0x011d43, 0x011d43},
+ {0x011d46, 0x011d46},
+ {0x011d47, 0x011d47},
+ {0x011d60, 0x011d65},
+ {0x011d67, 0x011d68},
+ {0x011d6a, 0x011d89},
+ {0x011d8a, 0x011d8e},
+ {0x011d90, 0x011d91},
+ {0x011d93, 0x011d94},
+ {0x011d95, 0x011d95},
+ {0x011d96, 0x011d96},
+ {0x011d98, 0x011d98},
+ {0x011ee0, 0x011ef2},
+ {0x011ef3, 0x011ef4},
+ {0x011ef5, 0x011ef6},
+ {0x011f00, 0x011f01},
+ {0x011f02, 0x011f02},
+ {0x011f03, 0x011f03},
+ {0x011f04, 0x011f10},
+ {0x011f12, 0x011f33},
+ {0x011f34, 0x011f35},
+ {0x011f36, 0x011f3a},
+ {0x011f3e, 0x011f3f},
+ {0x011f40, 0x011f40},
+ {0x011fb0, 0x011fb0},
+ {0x012000, 0x012399},
+ {0x012400, 0x01246e},
+ {0x012480, 0x012543},
+ {0x012f90, 0x012ff0},
+ {0x013000, 0x01342f},
+ {0x013441, 0x013446},
+ {0x014400, 0x014646},
+ {0x016800, 0x016a38},
+ {0x016a40, 0x016a5e},
+ {0x016a70, 0x016abe},
+ {0x016ad0, 0x016aed},
+ {0x016b00, 0x016b2f},
+ {0x016b40, 0x016b43},
+ {0x016b63, 0x016b77},
+ {0x016b7d, 0x016b8f},
+ {0x016e40, 0x016e7f},
+ {0x016f00, 0x016f4a},
+ {0x016f4f, 0x016f4f},
+ {0x016f50, 0x016f50},
+ {0x016f51, 0x016f87},
+ {0x016f8f, 0x016f92},
+ {0x016f93, 0x016f9f},
+ {0x016fe0, 0x016fe1},
+ {0x016fe3, 0x016fe3},
+ {0x016ff0, 0x016ff1},
+ {0x017000, 0x0187f7},
+ {0x018800, 0x018cd5},
+ {0x018d00, 0x018d08},
+ {0x01aff0, 0x01aff3},
+ {0x01aff5, 0x01affb},
+ {0x01affd, 0x01affe},
+ {0x01b000, 0x01b122},
+ {0x01b132, 0x01b132},
+ {0x01b150, 0x01b152},
+ {0x01b155, 0x01b155},
+ {0x01b164, 0x01b167},
+ {0x01b170, 0x01b2fb},
+ {0x01bc00, 0x01bc6a},
+ {0x01bc70, 0x01bc7c},
+ {0x01bc80, 0x01bc88},
+ {0x01bc90, 0x01bc99},
+ {0x01bc9e, 0x01bc9e},
+ {0x01d400, 0x01d454},
+ {0x01d456, 0x01d49c},
+ {0x01d49e, 0x01d49f},
+ {0x01d4a2, 0x01d4a2},
+ {0x01d4a5, 0x01d4a6},
+ {0x01d4a9, 0x01d4ac},
+ {0x01d4ae, 0x01d4b9},
+ {0x01d4bb, 0x01d4bb},
+ {0x01d4bd, 0x01d4c3},
+ {0x01d4c5, 0x01d505},
+ {0x01d507, 0x01d50a},
+ {0x01d50d, 0x01d514},
+ {0x01d516, 0x01d51c},
+ {0x01d51e, 0x01d539},
+ {0x01d53b, 0x01d53e},
+ {0x01d540, 0x01d544},
+ {0x01d546, 0x01d546},
+ {0x01d54a, 0x01d550},
+ {0x01d552, 0x01d6a5},
+ {0x01d6a8, 0x01d6c0},
+ {0x01d6c2, 0x01d6da},
+ {0x01d6dc, 0x01d6fa},
+ {0x01d6fc, 0x01d714},
+ {0x01d716, 0x01d734},
+ {0x01d736, 0x01d74e},
+ {0x01d750, 0x01d76e},
+ {0x01d770, 0x01d788},
+ {0x01d78a, 0x01d7a8},
+ {0x01d7aa, 0x01d7c2},
+ {0x01d7c4, 0x01d7cb},
+ {0x01df00, 0x01df09},
+ {0x01df0a, 0x01df0a},
+ {0x01df0b, 0x01df1e},
+ {0x01df25, 0x01df2a},
+ {0x01e000, 0x01e006},
+ {0x01e008, 0x01e018},
+ {0x01e01b, 0x01e021},
+ {0x01e023, 0x01e024},
+ {0x01e026, 0x01e02a},
+ {0x01e030, 0x01e06d},
+ {0x01e08f, 0x01e08f},
+ {0x01e100, 0x01e12c},
+ {0x01e137, 0x01e13d},
+ {0x01e14e, 0x01e14e},
+ {0x01e290, 0x01e2ad},
+ {0x01e2c0, 0x01e2eb},
+ {0x01e4d0, 0x01e4ea},
+ {0x01e4eb, 0x01e4eb},
+ {0x01e7e0, 0x01e7e6},
+ {0x01e7e8, 0x01e7eb},
+ {0x01e7ed, 0x01e7ee},
+ {0x01e7f0, 0x01e7fe},
+ {0x01e800, 0x01e8c4},
+ {0x01e900, 0x01e943},
+ {0x01e947, 0x01e947},
+ {0x01e94b, 0x01e94b},
+ {0x01ee00, 0x01ee03},
+ {0x01ee05, 0x01ee1f},
+ {0x01ee21, 0x01ee22},
+ {0x01ee24, 0x01ee24},
+ {0x01ee27, 0x01ee27},
+ {0x01ee29, 0x01ee32},
+ {0x01ee34, 0x01ee37},
+ {0x01ee39, 0x01ee39},
+ {0x01ee3b, 0x01ee3b},
+ {0x01ee42, 0x01ee42},
+ {0x01ee47, 0x01ee47},
+ {0x01ee49, 0x01ee49},
+ {0x01ee4b, 0x01ee4b},
+ {0x01ee4d, 0x01ee4f},
+ {0x01ee51, 0x01ee52},
+ {0x01ee54, 0x01ee54},
+ {0x01ee57, 0x01ee57},
+ {0x01ee59, 0x01ee59},
+ {0x01ee5b, 0x01ee5b},
+ {0x01ee5d, 0x01ee5d},
+ {0x01ee5f, 0x01ee5f},
+ {0x01ee61, 0x01ee62},
+ {0x01ee64, 0x01ee64},
+ {0x01ee67, 0x01ee6a},
+ {0x01ee6c, 0x01ee72},
+ {0x01ee74, 0x01ee77},
+ {0x01ee79, 0x01ee7c},
+ {0x01ee7e, 0x01ee7e},
+ {0x01ee80, 0x01ee89},
+ {0x01ee8b, 0x01ee9b},
+ {0x01eea1, 0x01eea3},
+ {0x01eea5, 0x01eea9},
+ {0x01eeab, 0x01eebb},
+ {0x01f130, 0x01f149},
+ {0x01f150, 0x01f169},
+ {0x01f170, 0x01f189},
+ {0x020000, 0x02a6df},
+ {0x02a700, 0x02b739},
+ {0x02b740, 0x02b81d},
+ {0x02b820, 0x02cea1},
+ {0x02ceb0, 0x02ebe0},
+ {0x02ebf0, 0x02ee5d},
+ {0x02f800, 0x02fa1d},
+ {0x030000, 0x03134a},
+ {0x031350, 0x0323af},
+};
+
+/* table of Unicode codepoint ranges of Lowercase characters */
+static const pg_unicode_range unicode_lowercase[686] =
+{
+ {0x000061, 0x00007a},
+ {0x0000aa, 0x0000aa},
+ {0x0000b5, 0x0000b5},
+ {0x0000ba, 0x0000ba},
+ {0x0000df, 0x0000f6},
+ {0x0000f8, 0x0000ff},
+ {0x000101, 0x000101},
+ {0x000103, 0x000103},
+ {0x000105, 0x000105},
+ {0x000107, 0x000107},
+ {0x000109, 0x000109},
+ {0x00010b, 0x00010b},
+ {0x00010d, 0x00010d},
+ {0x00010f, 0x00010f},
+ {0x000111, 0x000111},
+ {0x000113, 0x000113},
+ {0x000115, 0x000115},
+ {0x000117, 0x000117},
+ {0x000119, 0x000119},
+ {0x00011b, 0x00011b},
+ {0x00011d, 0x00011d},
+ {0x00011f, 0x00011f},
+ {0x000121, 0x000121},
+ {0x000123, 0x000123},
+ {0x000125, 0x000125},
+ {0x000127, 0x000127},
+ {0x000129, 0x000129},
+ {0x00012b, 0x00012b},
+ {0x00012d, 0x00012d},
+ {0x00012f, 0x00012f},
+ {0x000131, 0x000131},
+ {0x000133, 0x000133},
+ {0x000135, 0x000135},
+ {0x000137, 0x000138},
+ {0x00013a, 0x00013a},
+ {0x00013c, 0x00013c},
+ {0x00013e, 0x00013e},
+ {0x000140, 0x000140},
+ {0x000142, 0x000142},
+ {0x000144, 0x000144},
+ {0x000146, 0x000146},
+ {0x000148, 0x000149},
+ {0x00014b, 0x00014b},
+ {0x00014d, 0x00014d},
+ {0x00014f, 0x00014f},
+ {0x000151, 0x000151},
+ {0x000153, 0x000153},
+ {0x000155, 0x000155},
+ {0x000157, 0x000157},
+ {0x000159, 0x000159},
+ {0x00015b, 0x00015b},
+ {0x00015d, 0x00015d},
+ {0x00015f, 0x00015f},
+ {0x000161, 0x000161},
+ {0x000163, 0x000163},
+ {0x000165, 0x000165},
+ {0x000167, 0x000167},
+ {0x000169, 0x000169},
+ {0x00016b, 0x00016b},
+ {0x00016d, 0x00016d},
+ {0x00016f, 0x00016f},
+ {0x000171, 0x000171},
+ {0x000173, 0x000173},
+ {0x000175, 0x000175},
+ {0x000177, 0x000177},
+ {0x00017a, 0x00017a},
+ {0x00017c, 0x00017c},
+ {0x00017e, 0x000180},
+ {0x000183, 0x000183},
+ {0x000185, 0x000185},
+ {0x000188, 0x000188},
+ {0x00018c, 0x00018d},
+ {0x000192, 0x000192},
+ {0x000195, 0x000195},
+ {0x000199, 0x00019b},
+ {0x00019e, 0x00019e},
+ {0x0001a1, 0x0001a1},
+ {0x0001a3, 0x0001a3},
+ {0x0001a5, 0x0001a5},
+ {0x0001a8, 0x0001a8},
+ {0x0001aa, 0x0001ab},
+ {0x0001ad, 0x0001ad},
+ {0x0001b0, 0x0001b0},
+ {0x0001b4, 0x0001b4},
+ {0x0001b6, 0x0001b6},
+ {0x0001b9, 0x0001ba},
+ {0x0001bd, 0x0001bf},
+ {0x0001c6, 0x0001c6},
+ {0x0001c9, 0x0001c9},
+ {0x0001cc, 0x0001cc},
+ {0x0001ce, 0x0001ce},
+ {0x0001d0, 0x0001d0},
+ {0x0001d2, 0x0001d2},
+ {0x0001d4, 0x0001d4},
+ {0x0001d6, 0x0001d6},
+ {0x0001d8, 0x0001d8},
+ {0x0001da, 0x0001da},
+ {0x0001dc, 0x0001dd},
+ {0x0001df, 0x0001df},
+ {0x0001e1, 0x0001e1},
+ {0x0001e3, 0x0001e3},
+ {0x0001e5, 0x0001e5},
+ {0x0001e7, 0x0001e7},
+ {0x0001e9, 0x0001e9},
+ {0x0001eb, 0x0001eb},
+ {0x0001ed, 0x0001ed},
+ {0x0001ef, 0x0001f0},
+ {0x0001f3, 0x0001f3},
+ {0x0001f5, 0x0001f5},
+ {0x0001f9, 0x0001f9},
+ {0x0001fb, 0x0001fb},
+ {0x0001fd, 0x0001fd},
+ {0x0001ff, 0x0001ff},
+ {0x000201, 0x000201},
+ {0x000203, 0x000203},
+ {0x000205, 0x000205},
+ {0x000207, 0x000207},
+ {0x000209, 0x000209},
+ {0x00020b, 0x00020b},
+ {0x00020d, 0x00020d},
+ {0x00020f, 0x00020f},
+ {0x000211, 0x000211},
+ {0x000213, 0x000213},
+ {0x000215, 0x000215},
+ {0x000217, 0x000217},
+ {0x000219, 0x000219},
+ {0x00021b, 0x00021b},
+ {0x00021d, 0x00021d},
+ {0x00021f, 0x00021f},
+ {0x000221, 0x000221},
+ {0x000223, 0x000223},
+ {0x000225, 0x000225},
+ {0x000227, 0x000227},
+ {0x000229, 0x000229},
+ {0x00022b, 0x00022b},
+ {0x00022d, 0x00022d},
+ {0x00022f, 0x00022f},
+ {0x000231, 0x000231},
+ {0x000233, 0x000239},
+ {0x00023c, 0x00023c},
+ {0x00023f, 0x000240},
+ {0x000242, 0x000242},
+ {0x000247, 0x000247},
+ {0x000249, 0x000249},
+ {0x00024b, 0x00024b},
+ {0x00024d, 0x00024d},
+ {0x00024f, 0x000293},
+ {0x000295, 0x0002af},
+ {0x0002b0, 0x0002b8},
+ {0x0002c0, 0x0002c1},
+ {0x0002e0, 0x0002e4},
+ {0x000345, 0x000345},
+ {0x000371, 0x000371},
+ {0x000373, 0x000373},
+ {0x000377, 0x000377},
+ {0x00037a, 0x00037a},
+ {0x00037b, 0x00037d},
+ {0x000390, 0x000390},
+ {0x0003ac, 0x0003ce},
+ {0x0003d0, 0x0003d1},
+ {0x0003d5, 0x0003d7},
+ {0x0003d9, 0x0003d9},
+ {0x0003db, 0x0003db},
+ {0x0003dd, 0x0003dd},
+ {0x0003df, 0x0003df},
+ {0x0003e1, 0x0003e1},
+ {0x0003e3, 0x0003e3},
+ {0x0003e5, 0x0003e5},
+ {0x0003e7, 0x0003e7},
+ {0x0003e9, 0x0003e9},
+ {0x0003eb, 0x0003eb},
+ {0x0003ed, 0x0003ed},
+ {0x0003ef, 0x0003f3},
+ {0x0003f5, 0x0003f5},
+ {0x0003f8, 0x0003f8},
+ {0x0003fb, 0x0003fc},
+ {0x000430, 0x00045f},
+ {0x000461, 0x000461},
+ {0x000463, 0x000463},
+ {0x000465, 0x000465},
+ {0x000467, 0x000467},
+ {0x000469, 0x000469},
+ {0x00046b, 0x00046b},
+ {0x00046d, 0x00046d},
+ {0x00046f, 0x00046f},
+ {0x000471, 0x000471},
+ {0x000473, 0x000473},
+ {0x000475, 0x000475},
+ {0x000477, 0x000477},
+ {0x000479, 0x000479},
+ {0x00047b, 0x00047b},
+ {0x00047d, 0x00047d},
+ {0x00047f, 0x00047f},
+ {0x000481, 0x000481},
+ {0x00048b, 0x00048b},
+ {0x00048d, 0x00048d},
+ {0x00048f, 0x00048f},
+ {0x000491, 0x000491},
+ {0x000493, 0x000493},
+ {0x000495, 0x000495},
+ {0x000497, 0x000497},
+ {0x000499, 0x000499},
+ {0x00049b, 0x00049b},
+ {0x00049d, 0x00049d},
+ {0x00049f, 0x00049f},
+ {0x0004a1, 0x0004a1},
+ {0x0004a3, 0x0004a3},
+ {0x0004a5, 0x0004a5},
+ {0x0004a7, 0x0004a7},
+ {0x0004a9, 0x0004a9},
+ {0x0004ab, 0x0004ab},
+ {0x0004ad, 0x0004ad},
+ {0x0004af, 0x0004af},
+ {0x0004b1, 0x0004b1},
+ {0x0004b3, 0x0004b3},
+ {0x0004b5, 0x0004b5},
+ {0x0004b7, 0x0004b7},
+ {0x0004b9, 0x0004b9},
+ {0x0004bb, 0x0004bb},
+ {0x0004bd, 0x0004bd},
+ {0x0004bf, 0x0004bf},
+ {0x0004c2, 0x0004c2},
+ {0x0004c4, 0x0004c4},
+ {0x0004c6, 0x0004c6},
+ {0x0004c8, 0x0004c8},
+ {0x0004ca, 0x0004ca},
+ {0x0004cc, 0x0004cc},
+ {0x0004ce, 0x0004cf},
+ {0x0004d1, 0x0004d1},
+ {0x0004d3, 0x0004d3},
+ {0x0004d5, 0x0004d5},
+ {0x0004d7, 0x0004d7},
+ {0x0004d9, 0x0004d9},
+ {0x0004db, 0x0004db},
+ {0x0004dd, 0x0004dd},
+ {0x0004df, 0x0004df},
+ {0x0004e1, 0x0004e1},
+ {0x0004e3, 0x0004e3},
+ {0x0004e5, 0x0004e5},
+ {0x0004e7, 0x0004e7},
+ {0x0004e9, 0x0004e9},
+ {0x0004eb, 0x0004eb},
+ {0x0004ed, 0x0004ed},
+ {0x0004ef, 0x0004ef},
+ {0x0004f1, 0x0004f1},
+ {0x0004f3, 0x0004f3},
+ {0x0004f5, 0x0004f5},
+ {0x0004f7, 0x0004f7},
+ {0x0004f9, 0x0004f9},
+ {0x0004fb, 0x0004fb},
+ {0x0004fd, 0x0004fd},
+ {0x0004ff, 0x0004ff},
+ {0x000501, 0x000501},
+ {0x000503, 0x000503},
+ {0x000505, 0x000505},
+ {0x000507, 0x000507},
+ {0x000509, 0x000509},
+ {0x00050b, 0x00050b},
+ {0x00050d, 0x00050d},
+ {0x00050f, 0x00050f},
+ {0x000511, 0x000511},
+ {0x000513, 0x000513},
+ {0x000515, 0x000515},
+ {0x000517, 0x000517},
+ {0x000519, 0x000519},
+ {0x00051b, 0x00051b},
+ {0x00051d, 0x00051d},
+ {0x00051f, 0x00051f},
+ {0x000521, 0x000521},
+ {0x000523, 0x000523},
+ {0x000525, 0x000525},
+ {0x000527, 0x000527},
+ {0x000529, 0x000529},
+ {0x00052b, 0x00052b},
+ {0x00052d, 0x00052d},
+ {0x00052f, 0x00052f},
+ {0x000560, 0x000588},
+ {0x0010d0, 0x0010fa},
+ {0x0010fc, 0x0010fc},
+ {0x0010fd, 0x0010ff},
+ {0x0013f8, 0x0013fd},
+ {0x001c80, 0x001c88},
+ {0x001d00, 0x001d2b},
+ {0x001d2c, 0x001d6a},
+ {0x001d6b, 0x001d77},
+ {0x001d78, 0x001d78},
+ {0x001d79, 0x001d9a},
+ {0x001d9b, 0x001dbf},
+ {0x001e01, 0x001e01},
+ {0x001e03, 0x001e03},
+ {0x001e05, 0x001e05},
+ {0x001e07, 0x001e07},
+ {0x001e09, 0x001e09},
+ {0x001e0b, 0x001e0b},
+ {0x001e0d, 0x001e0d},
+ {0x001e0f, 0x001e0f},
+ {0x001e11, 0x001e11},
+ {0x001e13, 0x001e13},
+ {0x001e15, 0x001e15},
+ {0x001e17, 0x001e17},
+ {0x001e19, 0x001e19},
+ {0x001e1b, 0x001e1b},
+ {0x001e1d, 0x001e1d},
+ {0x001e1f, 0x001e1f},
+ {0x001e21, 0x001e21},
+ {0x001e23, 0x001e23},
+ {0x001e25, 0x001e25},
+ {0x001e27, 0x001e27},
+ {0x001e29, 0x001e29},
+ {0x001e2b, 0x001e2b},
+ {0x001e2d, 0x001e2d},
+ {0x001e2f, 0x001e2f},
+ {0x001e31, 0x001e31},
+ {0x001e33, 0x001e33},
+ {0x001e35, 0x001e35},
+ {0x001e37, 0x001e37},
+ {0x001e39, 0x001e39},
+ {0x001e3b, 0x001e3b},
+ {0x001e3d, 0x001e3d},
+ {0x001e3f, 0x001e3f},
+ {0x001e41, 0x001e41},
+ {0x001e43, 0x001e43},
+ {0x001e45, 0x001e45},
+ {0x001e47, 0x001e47},
+ {0x001e49, 0x001e49},
+ {0x001e4b, 0x001e4b},
+ {0x001e4d, 0x001e4d},
+ {0x001e4f, 0x001e4f},
+ {0x001e51, 0x001e51},
+ {0x001e53, 0x001e53},
+ {0x001e55, 0x001e55},
+ {0x001e57, 0x001e57},
+ {0x001e59, 0x001e59},
+ {0x001e5b, 0x001e5b},
+ {0x001e5d, 0x001e5d},
+ {0x001e5f, 0x001e5f},
+ {0x001e61, 0x001e61},
+ {0x001e63, 0x001e63},
+ {0x001e65, 0x001e65},
+ {0x001e67, 0x001e67},
+ {0x001e69, 0x001e69},
+ {0x001e6b, 0x001e6b},
+ {0x001e6d, 0x001e6d},
+ {0x001e6f, 0x001e6f},
+ {0x001e71, 0x001e71},
+ {0x001e73, 0x001e73},
+ {0x001e75, 0x001e75},
+ {0x001e77, 0x001e77},
+ {0x001e79, 0x001e79},
+ {0x001e7b, 0x001e7b},
+ {0x001e7d, 0x001e7d},
+ {0x001e7f, 0x001e7f},
+ {0x001e81, 0x001e81},
+ {0x001e83, 0x001e83},
+ {0x001e85, 0x001e85},
+ {0x001e87, 0x001e87},
+ {0x001e89, 0x001e89},
+ {0x001e8b, 0x001e8b},
+ {0x001e8d, 0x001e8d},
+ {0x001e8f, 0x001e8f},
+ {0x001e91, 0x001e91},
+ {0x001e93, 0x001e93},
+ {0x001e95, 0x001e9d},
+ {0x001e9f, 0x001e9f},
+ {0x001ea1, 0x001ea1},
+ {0x001ea3, 0x001ea3},
+ {0x001ea5, 0x001ea5},
+ {0x001ea7, 0x001ea7},
+ {0x001ea9, 0x001ea9},
+ {0x001eab, 0x001eab},
+ {0x001ead, 0x001ead},
+ {0x001eaf, 0x001eaf},
+ {0x001eb1, 0x001eb1},
+ {0x001eb3, 0x001eb3},
+ {0x001eb5, 0x001eb5},
+ {0x001eb7, 0x001eb7},
+ {0x001eb9, 0x001eb9},
+ {0x001ebb, 0x001ebb},
+ {0x001ebd, 0x001ebd},
+ {0x001ebf, 0x001ebf},
+ {0x001ec1, 0x001ec1},
+ {0x001ec3, 0x001ec3},
+ {0x001ec5, 0x001ec5},
+ {0x001ec7, 0x001ec7},
+ {0x001ec9, 0x001ec9},
+ {0x001ecb, 0x001ecb},
+ {0x001ecd, 0x001ecd},
+ {0x001ecf, 0x001ecf},
+ {0x001ed1, 0x001ed1},
+ {0x001ed3, 0x001ed3},
+ {0x001ed5, 0x001ed5},
+ {0x001ed7, 0x001ed7},
+ {0x001ed9, 0x001ed9},
+ {0x001edb, 0x001edb},
+ {0x001edd, 0x001edd},
+ {0x001edf, 0x001edf},
+ {0x001ee1, 0x001ee1},
+ {0x001ee3, 0x001ee3},
+ {0x001ee5, 0x001ee5},
+ {0x001ee7, 0x001ee7},
+ {0x001ee9, 0x001ee9},
+ {0x001eeb, 0x001eeb},
+ {0x001eed, 0x001eed},
+ {0x001eef, 0x001eef},
+ {0x001ef1, 0x001ef1},
+ {0x001ef3, 0x001ef3},
+ {0x001ef5, 0x001ef5},
+ {0x001ef7, 0x001ef7},
+ {0x001ef9, 0x001ef9},
+ {0x001efb, 0x001efb},
+ {0x001efd, 0x001efd},
+ {0x001eff, 0x001f07},
+ {0x001f10, 0x001f15},
+ {0x001f20, 0x001f27},
+ {0x001f30, 0x001f37},
+ {0x001f40, 0x001f45},
+ {0x001f50, 0x001f57},
+ {0x001f60, 0x001f67},
+ {0x001f70, 0x001f7d},
+ {0x001f80, 0x001f87},
+ {0x001f90, 0x001f97},
+ {0x001fa0, 0x001fa7},
+ {0x001fb0, 0x001fb4},
+ {0x001fb6, 0x001fb7},
+ {0x001fbe, 0x001fbe},
+ {0x001fc2, 0x001fc4},
+ {0x001fc6, 0x001fc7},
+ {0x001fd0, 0x001fd3},
+ {0x001fd6, 0x001fd7},
+ {0x001fe0, 0x001fe7},
+ {0x001ff2, 0x001ff4},
+ {0x001ff6, 0x001ff7},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x00210a, 0x00210a},
+ {0x00210e, 0x00210f},
+ {0x002113, 0x002113},
+ {0x00212f, 0x00212f},
+ {0x002134, 0x002134},
+ {0x002139, 0x002139},
+ {0x00213c, 0x00213d},
+ {0x002146, 0x002149},
+ {0x00214e, 0x00214e},
+ {0x002170, 0x00217f},
+ {0x002184, 0x002184},
+ {0x0024d0, 0x0024e9},
+ {0x002c30, 0x002c5f},
+ {0x002c61, 0x002c61},
+ {0x002c65, 0x002c66},
+ {0x002c68, 0x002c68},
+ {0x002c6a, 0x002c6a},
+ {0x002c6c, 0x002c6c},
+ {0x002c71, 0x002c71},
+ {0x002c73, 0x002c74},
+ {0x002c76, 0x002c7b},
+ {0x002c7c, 0x002c7d},
+ {0x002c81, 0x002c81},
+ {0x002c83, 0x002c83},
+ {0x002c85, 0x002c85},
+ {0x002c87, 0x002c87},
+ {0x002c89, 0x002c89},
+ {0x002c8b, 0x002c8b},
+ {0x002c8d, 0x002c8d},
+ {0x002c8f, 0x002c8f},
+ {0x002c91, 0x002c91},
+ {0x002c93, 0x002c93},
+ {0x002c95, 0x002c95},
+ {0x002c97, 0x002c97},
+ {0x002c99, 0x002c99},
+ {0x002c9b, 0x002c9b},
+ {0x002c9d, 0x002c9d},
+ {0x002c9f, 0x002c9f},
+ {0x002ca1, 0x002ca1},
+ {0x002ca3, 0x002ca3},
+ {0x002ca5, 0x002ca5},
+ {0x002ca7, 0x002ca7},
+ {0x002ca9, 0x002ca9},
+ {0x002cab, 0x002cab},
+ {0x002cad, 0x002cad},
+ {0x002caf, 0x002caf},
+ {0x002cb1, 0x002cb1},
+ {0x002cb3, 0x002cb3},
+ {0x002cb5, 0x002cb5},
+ {0x002cb7, 0x002cb7},
+ {0x002cb9, 0x002cb9},
+ {0x002cbb, 0x002cbb},
+ {0x002cbd, 0x002cbd},
+ {0x002cbf, 0x002cbf},
+ {0x002cc1, 0x002cc1},
+ {0x002cc3, 0x002cc3},
+ {0x002cc5, 0x002cc5},
+ {0x002cc7, 0x002cc7},
+ {0x002cc9, 0x002cc9},
+ {0x002ccb, 0x002ccb},
+ {0x002ccd, 0x002ccd},
+ {0x002ccf, 0x002ccf},
+ {0x002cd1, 0x002cd1},
+ {0x002cd3, 0x002cd3},
+ {0x002cd5, 0x002cd5},
+ {0x002cd7, 0x002cd7},
+ {0x002cd9, 0x002cd9},
+ {0x002cdb, 0x002cdb},
+ {0x002cdd, 0x002cdd},
+ {0x002cdf, 0x002cdf},
+ {0x002ce1, 0x002ce1},
+ {0x002ce3, 0x002ce4},
+ {0x002cec, 0x002cec},
+ {0x002cee, 0x002cee},
+ {0x002cf3, 0x002cf3},
+ {0x002d00, 0x002d25},
+ {0x002d27, 0x002d27},
+ {0x002d2d, 0x002d2d},
+ {0x00a641, 0x00a641},
+ {0x00a643, 0x00a643},
+ {0x00a645, 0x00a645},
+ {0x00a647, 0x00a647},
+ {0x00a649, 0x00a649},
+ {0x00a64b, 0x00a64b},
+ {0x00a64d, 0x00a64d},
+ {0x00a64f, 0x00a64f},
+ {0x00a651, 0x00a651},
+ {0x00a653, 0x00a653},
+ {0x00a655, 0x00a655},
+ {0x00a657, 0x00a657},
+ {0x00a659, 0x00a659},
+ {0x00a65b, 0x00a65b},
+ {0x00a65d, 0x00a65d},
+ {0x00a65f, 0x00a65f},
+ {0x00a661, 0x00a661},
+ {0x00a663, 0x00a663},
+ {0x00a665, 0x00a665},
+ {0x00a667, 0x00a667},
+ {0x00a669, 0x00a669},
+ {0x00a66b, 0x00a66b},
+ {0x00a66d, 0x00a66d},
+ {0x00a681, 0x00a681},
+ {0x00a683, 0x00a683},
+ {0x00a685, 0x00a685},
+ {0x00a687, 0x00a687},
+ {0x00a689, 0x00a689},
+ {0x00a68b, 0x00a68b},
+ {0x00a68d, 0x00a68d},
+ {0x00a68f, 0x00a68f},
+ {0x00a691, 0x00a691},
+ {0x00a693, 0x00a693},
+ {0x00a695, 0x00a695},
+ {0x00a697, 0x00a697},
+ {0x00a699, 0x00a699},
+ {0x00a69b, 0x00a69b},
+ {0x00a69c, 0x00a69d},
+ {0x00a723, 0x00a723},
+ {0x00a725, 0x00a725},
+ {0x00a727, 0x00a727},
+ {0x00a729, 0x00a729},
+ {0x00a72b, 0x00a72b},
+ {0x00a72d, 0x00a72d},
+ {0x00a72f, 0x00a731},
+ {0x00a733, 0x00a733},
+ {0x00a735, 0x00a735},
+ {0x00a737, 0x00a737},
+ {0x00a739, 0x00a739},
+ {0x00a73b, 0x00a73b},
+ {0x00a73d, 0x00a73d},
+ {0x00a73f, 0x00a73f},
+ {0x00a741, 0x00a741},
+ {0x00a743, 0x00a743},
+ {0x00a745, 0x00a745},
+ {0x00a747, 0x00a747},
+ {0x00a749, 0x00a749},
+ {0x00a74b, 0x00a74b},
+ {0x00a74d, 0x00a74d},
+ {0x00a74f, 0x00a74f},
+ {0x00a751, 0x00a751},
+ {0x00a753, 0x00a753},
+ {0x00a755, 0x00a755},
+ {0x00a757, 0x00a757},
+ {0x00a759, 0x00a759},
+ {0x00a75b, 0x00a75b},
+ {0x00a75d, 0x00a75d},
+ {0x00a75f, 0x00a75f},
+ {0x00a761, 0x00a761},
+ {0x00a763, 0x00a763},
+ {0x00a765, 0x00a765},
+ {0x00a767, 0x00a767},
+ {0x00a769, 0x00a769},
+ {0x00a76b, 0x00a76b},
+ {0x00a76d, 0x00a76d},
+ {0x00a76f, 0x00a76f},
+ {0x00a770, 0x00a770},
+ {0x00a771, 0x00a778},
+ {0x00a77a, 0x00a77a},
+ {0x00a77c, 0x00a77c},
+ {0x00a77f, 0x00a77f},
+ {0x00a781, 0x00a781},
+ {0x00a783, 0x00a783},
+ {0x00a785, 0x00a785},
+ {0x00a787, 0x00a787},
+ {0x00a78c, 0x00a78c},
+ {0x00a78e, 0x00a78e},
+ {0x00a791, 0x00a791},
+ {0x00a793, 0x00a795},
+ {0x00a797, 0x00a797},
+ {0x00a799, 0x00a799},
+ {0x00a79b, 0x00a79b},
+ {0x00a79d, 0x00a79d},
+ {0x00a79f, 0x00a79f},
+ {0x00a7a1, 0x00a7a1},
+ {0x00a7a3, 0x00a7a3},
+ {0x00a7a5, 0x00a7a5},
+ {0x00a7a7, 0x00a7a7},
+ {0x00a7a9, 0x00a7a9},
+ {0x00a7af, 0x00a7af},
+ {0x00a7b5, 0x00a7b5},
+ {0x00a7b7, 0x00a7b7},
+ {0x00a7b9, 0x00a7b9},
+ {0x00a7bb, 0x00a7bb},
+ {0x00a7bd, 0x00a7bd},
+ {0x00a7bf, 0x00a7bf},
+ {0x00a7c1, 0x00a7c1},
+ {0x00a7c3, 0x00a7c3},
+ {0x00a7c8, 0x00a7c8},
+ {0x00a7ca, 0x00a7ca},
+ {0x00a7d1, 0x00a7d1},
+ {0x00a7d3, 0x00a7d3},
+ {0x00a7d5, 0x00a7d5},
+ {0x00a7d7, 0x00a7d7},
+ {0x00a7d9, 0x00a7d9},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f6, 0x00a7f6},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a7fa, 0x00a7fa},
+ {0x00ab30, 0x00ab5a},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab60, 0x00ab68},
+ {0x00ab69, 0x00ab69},
+ {0x00ab70, 0x00abbf},
+ {0x00fb00, 0x00fb06},
+ {0x00fb13, 0x00fb17},
+ {0x00ff41, 0x00ff5a},
+ {0x010428, 0x01044f},
+ {0x0104d8, 0x0104fb},
+ {0x010597, 0x0105a1},
+ {0x0105a3, 0x0105b1},
+ {0x0105b3, 0x0105b9},
+ {0x0105bb, 0x0105bc},
+ {0x010780, 0x010780},
+ {0x010783, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010cc0, 0x010cf2},
+ {0x0118c0, 0x0118df},
+ {0x016e60, 0x016e7f},
+ {0x01d41a, 0x01d433},
+ {0x01d44e, 0x01d454},
+ {0x01d456, 0x01d467},
+ {0x01d482, 0x01d49b},
+ {0x01d4b6, 0x01d4b9},
+ {0x01d4bb, 0x01d4bb},
+ {0x01d4bd, 0x01d4c3},
+ {0x01d4c5, 0x01d4cf},
+ {0x01d4ea, 0x01d503},
+ {0x01d51e, 0x01d537},
+ {0x01d552, 0x01d56b},
+ {0x01d586, 0x01d59f},
+ {0x01d5ba, 0x01d5d3},
+ {0x01d5ee, 0x01d607},
+ {0x01d622, 0x01d63b},
+ {0x01d656, 0x01d66f},
+ {0x01d68a, 0x01d6a5},
+ {0x01d6c2, 0x01d6da},
+ {0x01d6dc, 0x01d6e1},
+ {0x01d6fc, 0x01d714},
+ {0x01d716, 0x01d71b},
+ {0x01d736, 0x01d74e},
+ {0x01d750, 0x01d755},
+ {0x01d770, 0x01d788},
+ {0x01d78a, 0x01d78f},
+ {0x01d7aa, 0x01d7c2},
+ {0x01d7c4, 0x01d7c9},
+ {0x01d7cb, 0x01d7cb},
+ {0x01df00, 0x01df09},
+ {0x01df0b, 0x01df1e},
+ {0x01df25, 0x01df2a},
+ {0x01e030, 0x01e06d},
+ {0x01e922, 0x01e943},
+};
+
+/* table of Unicode codepoint ranges of Uppercase characters */
+static const pg_unicode_range unicode_uppercase[651] =
+{
+ {0x000041, 0x00005a},
+ {0x0000c0, 0x0000d6},
+ {0x0000d8, 0x0000de},
+ {0x000100, 0x000100},
+ {0x000102, 0x000102},
+ {0x000104, 0x000104},
+ {0x000106, 0x000106},
+ {0x000108, 0x000108},
+ {0x00010a, 0x00010a},
+ {0x00010c, 0x00010c},
+ {0x00010e, 0x00010e},
+ {0x000110, 0x000110},
+ {0x000112, 0x000112},
+ {0x000114, 0x000114},
+ {0x000116, 0x000116},
+ {0x000118, 0x000118},
+ {0x00011a, 0x00011a},
+ {0x00011c, 0x00011c},
+ {0x00011e, 0x00011e},
+ {0x000120, 0x000120},
+ {0x000122, 0x000122},
+ {0x000124, 0x000124},
+ {0x000126, 0x000126},
+ {0x000128, 0x000128},
+ {0x00012a, 0x00012a},
+ {0x00012c, 0x00012c},
+ {0x00012e, 0x00012e},
+ {0x000130, 0x000130},
+ {0x000132, 0x000132},
+ {0x000134, 0x000134},
+ {0x000136, 0x000136},
+ {0x000139, 0x000139},
+ {0x00013b, 0x00013b},
+ {0x00013d, 0x00013d},
+ {0x00013f, 0x00013f},
+ {0x000141, 0x000141},
+ {0x000143, 0x000143},
+ {0x000145, 0x000145},
+ {0x000147, 0x000147},
+ {0x00014a, 0x00014a},
+ {0x00014c, 0x00014c},
+ {0x00014e, 0x00014e},
+ {0x000150, 0x000150},
+ {0x000152, 0x000152},
+ {0x000154, 0x000154},
+ {0x000156, 0x000156},
+ {0x000158, 0x000158},
+ {0x00015a, 0x00015a},
+ {0x00015c, 0x00015c},
+ {0x00015e, 0x00015e},
+ {0x000160, 0x000160},
+ {0x000162, 0x000162},
+ {0x000164, 0x000164},
+ {0x000166, 0x000166},
+ {0x000168, 0x000168},
+ {0x00016a, 0x00016a},
+ {0x00016c, 0x00016c},
+ {0x00016e, 0x00016e},
+ {0x000170, 0x000170},
+ {0x000172, 0x000172},
+ {0x000174, 0x000174},
+ {0x000176, 0x000176},
+ {0x000178, 0x000179},
+ {0x00017b, 0x00017b},
+ {0x00017d, 0x00017d},
+ {0x000181, 0x000182},
+ {0x000184, 0x000184},
+ {0x000186, 0x000187},
+ {0x000189, 0x00018b},
+ {0x00018e, 0x000191},
+ {0x000193, 0x000194},
+ {0x000196, 0x000198},
+ {0x00019c, 0x00019d},
+ {0x00019f, 0x0001a0},
+ {0x0001a2, 0x0001a2},
+ {0x0001a4, 0x0001a4},
+ {0x0001a6, 0x0001a7},
+ {0x0001a9, 0x0001a9},
+ {0x0001ac, 0x0001ac},
+ {0x0001ae, 0x0001af},
+ {0x0001b1, 0x0001b3},
+ {0x0001b5, 0x0001b5},
+ {0x0001b7, 0x0001b8},
+ {0x0001bc, 0x0001bc},
+ {0x0001c4, 0x0001c4},
+ {0x0001c7, 0x0001c7},
+ {0x0001ca, 0x0001ca},
+ {0x0001cd, 0x0001cd},
+ {0x0001cf, 0x0001cf},
+ {0x0001d1, 0x0001d1},
+ {0x0001d3, 0x0001d3},
+ {0x0001d5, 0x0001d5},
+ {0x0001d7, 0x0001d7},
+ {0x0001d9, 0x0001d9},
+ {0x0001db, 0x0001db},
+ {0x0001de, 0x0001de},
+ {0x0001e0, 0x0001e0},
+ {0x0001e2, 0x0001e2},
+ {0x0001e4, 0x0001e4},
+ {0x0001e6, 0x0001e6},
+ {0x0001e8, 0x0001e8},
+ {0x0001ea, 0x0001ea},
+ {0x0001ec, 0x0001ec},
+ {0x0001ee, 0x0001ee},
+ {0x0001f1, 0x0001f1},
+ {0x0001f4, 0x0001f4},
+ {0x0001f6, 0x0001f8},
+ {0x0001fa, 0x0001fa},
+ {0x0001fc, 0x0001fc},
+ {0x0001fe, 0x0001fe},
+ {0x000200, 0x000200},
+ {0x000202, 0x000202},
+ {0x000204, 0x000204},
+ {0x000206, 0x000206},
+ {0x000208, 0x000208},
+ {0x00020a, 0x00020a},
+ {0x00020c, 0x00020c},
+ {0x00020e, 0x00020e},
+ {0x000210, 0x000210},
+ {0x000212, 0x000212},
+ {0x000214, 0x000214},
+ {0x000216, 0x000216},
+ {0x000218, 0x000218},
+ {0x00021a, 0x00021a},
+ {0x00021c, 0x00021c},
+ {0x00021e, 0x00021e},
+ {0x000220, 0x000220},
+ {0x000222, 0x000222},
+ {0x000224, 0x000224},
+ {0x000226, 0x000226},
+ {0x000228, 0x000228},
+ {0x00022a, 0x00022a},
+ {0x00022c, 0x00022c},
+ {0x00022e, 0x00022e},
+ {0x000230, 0x000230},
+ {0x000232, 0x000232},
+ {0x00023a, 0x00023b},
+ {0x00023d, 0x00023e},
+ {0x000241, 0x000241},
+ {0x000243, 0x000246},
+ {0x000248, 0x000248},
+ {0x00024a, 0x00024a},
+ {0x00024c, 0x00024c},
+ {0x00024e, 0x00024e},
+ {0x000370, 0x000370},
+ {0x000372, 0x000372},
+ {0x000376, 0x000376},
+ {0x00037f, 0x00037f},
+ {0x000386, 0x000386},
+ {0x000388, 0x00038a},
+ {0x00038c, 0x00038c},
+ {0x00038e, 0x00038f},
+ {0x000391, 0x0003a1},
+ {0x0003a3, 0x0003ab},
+ {0x0003cf, 0x0003cf},
+ {0x0003d2, 0x0003d4},
+ {0x0003d8, 0x0003d8},
+ {0x0003da, 0x0003da},
+ {0x0003dc, 0x0003dc},
+ {0x0003de, 0x0003de},
+ {0x0003e0, 0x0003e0},
+ {0x0003e2, 0x0003e2},
+ {0x0003e4, 0x0003e4},
+ {0x0003e6, 0x0003e6},
+ {0x0003e8, 0x0003e8},
+ {0x0003ea, 0x0003ea},
+ {0x0003ec, 0x0003ec},
+ {0x0003ee, 0x0003ee},
+ {0x0003f4, 0x0003f4},
+ {0x0003f7, 0x0003f7},
+ {0x0003f9, 0x0003fa},
+ {0x0003fd, 0x00042f},
+ {0x000460, 0x000460},
+ {0x000462, 0x000462},
+ {0x000464, 0x000464},
+ {0x000466, 0x000466},
+ {0x000468, 0x000468},
+ {0x00046a, 0x00046a},
+ {0x00046c, 0x00046c},
+ {0x00046e, 0x00046e},
+ {0x000470, 0x000470},
+ {0x000472, 0x000472},
+ {0x000474, 0x000474},
+ {0x000476, 0x000476},
+ {0x000478, 0x000478},
+ {0x00047a, 0x00047a},
+ {0x00047c, 0x00047c},
+ {0x00047e, 0x00047e},
+ {0x000480, 0x000480},
+ {0x00048a, 0x00048a},
+ {0x00048c, 0x00048c},
+ {0x00048e, 0x00048e},
+ {0x000490, 0x000490},
+ {0x000492, 0x000492},
+ {0x000494, 0x000494},
+ {0x000496, 0x000496},
+ {0x000498, 0x000498},
+ {0x00049a, 0x00049a},
+ {0x00049c, 0x00049c},
+ {0x00049e, 0x00049e},
+ {0x0004a0, 0x0004a0},
+ {0x0004a2, 0x0004a2},
+ {0x0004a4, 0x0004a4},
+ {0x0004a6, 0x0004a6},
+ {0x0004a8, 0x0004a8},
+ {0x0004aa, 0x0004aa},
+ {0x0004ac, 0x0004ac},
+ {0x0004ae, 0x0004ae},
+ {0x0004b0, 0x0004b0},
+ {0x0004b2, 0x0004b2},
+ {0x0004b4, 0x0004b4},
+ {0x0004b6, 0x0004b6},
+ {0x0004b8, 0x0004b8},
+ {0x0004ba, 0x0004ba},
+ {0x0004bc, 0x0004bc},
+ {0x0004be, 0x0004be},
+ {0x0004c0, 0x0004c1},
+ {0x0004c3, 0x0004c3},
+ {0x0004c5, 0x0004c5},
+ {0x0004c7, 0x0004c7},
+ {0x0004c9, 0x0004c9},
+ {0x0004cb, 0x0004cb},
+ {0x0004cd, 0x0004cd},
+ {0x0004d0, 0x0004d0},
+ {0x0004d2, 0x0004d2},
+ {0x0004d4, 0x0004d4},
+ {0x0004d6, 0x0004d6},
+ {0x0004d8, 0x0004d8},
+ {0x0004da, 0x0004da},
+ {0x0004dc, 0x0004dc},
+ {0x0004de, 0x0004de},
+ {0x0004e0, 0x0004e0},
+ {0x0004e2, 0x0004e2},
+ {0x0004e4, 0x0004e4},
+ {0x0004e6, 0x0004e6},
+ {0x0004e8, 0x0004e8},
+ {0x0004ea, 0x0004ea},
+ {0x0004ec, 0x0004ec},
+ {0x0004ee, 0x0004ee},
+ {0x0004f0, 0x0004f0},
+ {0x0004f2, 0x0004f2},
+ {0x0004f4, 0x0004f4},
+ {0x0004f6, 0x0004f6},
+ {0x0004f8, 0x0004f8},
+ {0x0004fa, 0x0004fa},
+ {0x0004fc, 0x0004fc},
+ {0x0004fe, 0x0004fe},
+ {0x000500, 0x000500},
+ {0x000502, 0x000502},
+ {0x000504, 0x000504},
+ {0x000506, 0x000506},
+ {0x000508, 0x000508},
+ {0x00050a, 0x00050a},
+ {0x00050c, 0x00050c},
+ {0x00050e, 0x00050e},
+ {0x000510, 0x000510},
+ {0x000512, 0x000512},
+ {0x000514, 0x000514},
+ {0x000516, 0x000516},
+ {0x000518, 0x000518},
+ {0x00051a, 0x00051a},
+ {0x00051c, 0x00051c},
+ {0x00051e, 0x00051e},
+ {0x000520, 0x000520},
+ {0x000522, 0x000522},
+ {0x000524, 0x000524},
+ {0x000526, 0x000526},
+ {0x000528, 0x000528},
+ {0x00052a, 0x00052a},
+ {0x00052c, 0x00052c},
+ {0x00052e, 0x00052e},
+ {0x000531, 0x000556},
+ {0x0010a0, 0x0010c5},
+ {0x0010c7, 0x0010c7},
+ {0x0010cd, 0x0010cd},
+ {0x0013a0, 0x0013f5},
+ {0x001c90, 0x001cba},
+ {0x001cbd, 0x001cbf},
+ {0x001e00, 0x001e00},
+ {0x001e02, 0x001e02},
+ {0x001e04, 0x001e04},
+ {0x001e06, 0x001e06},
+ {0x001e08, 0x001e08},
+ {0x001e0a, 0x001e0a},
+ {0x001e0c, 0x001e0c},
+ {0x001e0e, 0x001e0e},
+ {0x001e10, 0x001e10},
+ {0x001e12, 0x001e12},
+ {0x001e14, 0x001e14},
+ {0x001e16, 0x001e16},
+ {0x001e18, 0x001e18},
+ {0x001e1a, 0x001e1a},
+ {0x001e1c, 0x001e1c},
+ {0x001e1e, 0x001e1e},
+ {0x001e20, 0x001e20},
+ {0x001e22, 0x001e22},
+ {0x001e24, 0x001e24},
+ {0x001e26, 0x001e26},
+ {0x001e28, 0x001e28},
+ {0x001e2a, 0x001e2a},
+ {0x001e2c, 0x001e2c},
+ {0x001e2e, 0x001e2e},
+ {0x001e30, 0x001e30},
+ {0x001e32, 0x001e32},
+ {0x001e34, 0x001e34},
+ {0x001e36, 0x001e36},
+ {0x001e38, 0x001e38},
+ {0x001e3a, 0x001e3a},
+ {0x001e3c, 0x001e3c},
+ {0x001e3e, 0x001e3e},
+ {0x001e40, 0x001e40},
+ {0x001e42, 0x001e42},
+ {0x001e44, 0x001e44},
+ {0x001e46, 0x001e46},
+ {0x001e48, 0x001e48},
+ {0x001e4a, 0x001e4a},
+ {0x001e4c, 0x001e4c},
+ {0x001e4e, 0x001e4e},
+ {0x001e50, 0x001e50},
+ {0x001e52, 0x001e52},
+ {0x001e54, 0x001e54},
+ {0x001e56, 0x001e56},
+ {0x001e58, 0x001e58},
+ {0x001e5a, 0x001e5a},
+ {0x001e5c, 0x001e5c},
+ {0x001e5e, 0x001e5e},
+ {0x001e60, 0x001e60},
+ {0x001e62, 0x001e62},
+ {0x001e64, 0x001e64},
+ {0x001e66, 0x001e66},
+ {0x001e68, 0x001e68},
+ {0x001e6a, 0x001e6a},
+ {0x001e6c, 0x001e6c},
+ {0x001e6e, 0x001e6e},
+ {0x001e70, 0x001e70},
+ {0x001e72, 0x001e72},
+ {0x001e74, 0x001e74},
+ {0x001e76, 0x001e76},
+ {0x001e78, 0x001e78},
+ {0x001e7a, 0x001e7a},
+ {0x001e7c, 0x001e7c},
+ {0x001e7e, 0x001e7e},
+ {0x001e80, 0x001e80},
+ {0x001e82, 0x001e82},
+ {0x001e84, 0x001e84},
+ {0x001e86, 0x001e86},
+ {0x001e88, 0x001e88},
+ {0x001e8a, 0x001e8a},
+ {0x001e8c, 0x001e8c},
+ {0x001e8e, 0x001e8e},
+ {0x001e90, 0x001e90},
+ {0x001e92, 0x001e92},
+ {0x001e94, 0x001e94},
+ {0x001e9e, 0x001e9e},
+ {0x001ea0, 0x001ea0},
+ {0x001ea2, 0x001ea2},
+ {0x001ea4, 0x001ea4},
+ {0x001ea6, 0x001ea6},
+ {0x001ea8, 0x001ea8},
+ {0x001eaa, 0x001eaa},
+ {0x001eac, 0x001eac},
+ {0x001eae, 0x001eae},
+ {0x001eb0, 0x001eb0},
+ {0x001eb2, 0x001eb2},
+ {0x001eb4, 0x001eb4},
+ {0x001eb6, 0x001eb6},
+ {0x001eb8, 0x001eb8},
+ {0x001eba, 0x001eba},
+ {0x001ebc, 0x001ebc},
+ {0x001ebe, 0x001ebe},
+ {0x001ec0, 0x001ec0},
+ {0x001ec2, 0x001ec2},
+ {0x001ec4, 0x001ec4},
+ {0x001ec6, 0x001ec6},
+ {0x001ec8, 0x001ec8},
+ {0x001eca, 0x001eca},
+ {0x001ecc, 0x001ecc},
+ {0x001ece, 0x001ece},
+ {0x001ed0, 0x001ed0},
+ {0x001ed2, 0x001ed2},
+ {0x001ed4, 0x001ed4},
+ {0x001ed6, 0x001ed6},
+ {0x001ed8, 0x001ed8},
+ {0x001eda, 0x001eda},
+ {0x001edc, 0x001edc},
+ {0x001ede, 0x001ede},
+ {0x001ee0, 0x001ee0},
+ {0x001ee2, 0x001ee2},
+ {0x001ee4, 0x001ee4},
+ {0x001ee6, 0x001ee6},
+ {0x001ee8, 0x001ee8},
+ {0x001eea, 0x001eea},
+ {0x001eec, 0x001eec},
+ {0x001eee, 0x001eee},
+ {0x001ef0, 0x001ef0},
+ {0x001ef2, 0x001ef2},
+ {0x001ef4, 0x001ef4},
+ {0x001ef6, 0x001ef6},
+ {0x001ef8, 0x001ef8},
+ {0x001efa, 0x001efa},
+ {0x001efc, 0x001efc},
+ {0x001efe, 0x001efe},
+ {0x001f08, 0x001f0f},
+ {0x001f18, 0x001f1d},
+ {0x001f28, 0x001f2f},
+ {0x001f38, 0x001f3f},
+ {0x001f48, 0x001f4d},
+ {0x001f59, 0x001f59},
+ {0x001f5b, 0x001f5b},
+ {0x001f5d, 0x001f5d},
+ {0x001f5f, 0x001f5f},
+ {0x001f68, 0x001f6f},
+ {0x001fb8, 0x001fbb},
+ {0x001fc8, 0x001fcb},
+ {0x001fd8, 0x001fdb},
+ {0x001fe8, 0x001fec},
+ {0x001ff8, 0x001ffb},
+ {0x002102, 0x002102},
+ {0x002107, 0x002107},
+ {0x00210b, 0x00210d},
+ {0x002110, 0x002112},
+ {0x002115, 0x002115},
+ {0x002119, 0x00211d},
+ {0x002124, 0x002124},
+ {0x002126, 0x002126},
+ {0x002128, 0x002128},
+ {0x00212a, 0x00212d},
+ {0x002130, 0x002133},
+ {0x00213e, 0x00213f},
+ {0x002145, 0x002145},
+ {0x002160, 0x00216f},
+ {0x002183, 0x002183},
+ {0x0024b6, 0x0024cf},
+ {0x002c00, 0x002c2f},
+ {0x002c60, 0x002c60},
+ {0x002c62, 0x002c64},
+ {0x002c67, 0x002c67},
+ {0x002c69, 0x002c69},
+ {0x002c6b, 0x002c6b},
+ {0x002c6d, 0x002c70},
+ {0x002c72, 0x002c72},
+ {0x002c75, 0x002c75},
+ {0x002c7e, 0x002c80},
+ {0x002c82, 0x002c82},
+ {0x002c84, 0x002c84},
+ {0x002c86, 0x002c86},
+ {0x002c88, 0x002c88},
+ {0x002c8a, 0x002c8a},
+ {0x002c8c, 0x002c8c},
+ {0x002c8e, 0x002c8e},
+ {0x002c90, 0x002c90},
+ {0x002c92, 0x002c92},
+ {0x002c94, 0x002c94},
+ {0x002c96, 0x002c96},
+ {0x002c98, 0x002c98},
+ {0x002c9a, 0x002c9a},
+ {0x002c9c, 0x002c9c},
+ {0x002c9e, 0x002c9e},
+ {0x002ca0, 0x002ca0},
+ {0x002ca2, 0x002ca2},
+ {0x002ca4, 0x002ca4},
+ {0x002ca6, 0x002ca6},
+ {0x002ca8, 0x002ca8},
+ {0x002caa, 0x002caa},
+ {0x002cac, 0x002cac},
+ {0x002cae, 0x002cae},
+ {0x002cb0, 0x002cb0},
+ {0x002cb2, 0x002cb2},
+ {0x002cb4, 0x002cb4},
+ {0x002cb6, 0x002cb6},
+ {0x002cb8, 0x002cb8},
+ {0x002cba, 0x002cba},
+ {0x002cbc, 0x002cbc},
+ {0x002cbe, 0x002cbe},
+ {0x002cc0, 0x002cc0},
+ {0x002cc2, 0x002cc2},
+ {0x002cc4, 0x002cc4},
+ {0x002cc6, 0x002cc6},
+ {0x002cc8, 0x002cc8},
+ {0x002cca, 0x002cca},
+ {0x002ccc, 0x002ccc},
+ {0x002cce, 0x002cce},
+ {0x002cd0, 0x002cd0},
+ {0x002cd2, 0x002cd2},
+ {0x002cd4, 0x002cd4},
+ {0x002cd6, 0x002cd6},
+ {0x002cd8, 0x002cd8},
+ {0x002cda, 0x002cda},
+ {0x002cdc, 0x002cdc},
+ {0x002cde, 0x002cde},
+ {0x002ce0, 0x002ce0},
+ {0x002ce2, 0x002ce2},
+ {0x002ceb, 0x002ceb},
+ {0x002ced, 0x002ced},
+ {0x002cf2, 0x002cf2},
+ {0x00a640, 0x00a640},
+ {0x00a642, 0x00a642},
+ {0x00a644, 0x00a644},
+ {0x00a646, 0x00a646},
+ {0x00a648, 0x00a648},
+ {0x00a64a, 0x00a64a},
+ {0x00a64c, 0x00a64c},
+ {0x00a64e, 0x00a64e},
+ {0x00a650, 0x00a650},
+ {0x00a652, 0x00a652},
+ {0x00a654, 0x00a654},
+ {0x00a656, 0x00a656},
+ {0x00a658, 0x00a658},
+ {0x00a65a, 0x00a65a},
+ {0x00a65c, 0x00a65c},
+ {0x00a65e, 0x00a65e},
+ {0x00a660, 0x00a660},
+ {0x00a662, 0x00a662},
+ {0x00a664, 0x00a664},
+ {0x00a666, 0x00a666},
+ {0x00a668, 0x00a668},
+ {0x00a66a, 0x00a66a},
+ {0x00a66c, 0x00a66c},
+ {0x00a680, 0x00a680},
+ {0x00a682, 0x00a682},
+ {0x00a684, 0x00a684},
+ {0x00a686, 0x00a686},
+ {0x00a688, 0x00a688},
+ {0x00a68a, 0x00a68a},
+ {0x00a68c, 0x00a68c},
+ {0x00a68e, 0x00a68e},
+ {0x00a690, 0x00a690},
+ {0x00a692, 0x00a692},
+ {0x00a694, 0x00a694},
+ {0x00a696, 0x00a696},
+ {0x00a698, 0x00a698},
+ {0x00a69a, 0x00a69a},
+ {0x00a722, 0x00a722},
+ {0x00a724, 0x00a724},
+ {0x00a726, 0x00a726},
+ {0x00a728, 0x00a728},
+ {0x00a72a, 0x00a72a},
+ {0x00a72c, 0x00a72c},
+ {0x00a72e, 0x00a72e},
+ {0x00a732, 0x00a732},
+ {0x00a734, 0x00a734},
+ {0x00a736, 0x00a736},
+ {0x00a738, 0x00a738},
+ {0x00a73a, 0x00a73a},
+ {0x00a73c, 0x00a73c},
+ {0x00a73e, 0x00a73e},
+ {0x00a740, 0x00a740},
+ {0x00a742, 0x00a742},
+ {0x00a744, 0x00a744},
+ {0x00a746, 0x00a746},
+ {0x00a748, 0x00a748},
+ {0x00a74a, 0x00a74a},
+ {0x00a74c, 0x00a74c},
+ {0x00a74e, 0x00a74e},
+ {0x00a750, 0x00a750},
+ {0x00a752, 0x00a752},
+ {0x00a754, 0x00a754},
+ {0x00a756, 0x00a756},
+ {0x00a758, 0x00a758},
+ {0x00a75a, 0x00a75a},
+ {0x00a75c, 0x00a75c},
+ {0x00a75e, 0x00a75e},
+ {0x00a760, 0x00a760},
+ {0x00a762, 0x00a762},
+ {0x00a764, 0x00a764},
+ {0x00a766, 0x00a766},
+ {0x00a768, 0x00a768},
+ {0x00a76a, 0x00a76a},
+ {0x00a76c, 0x00a76c},
+ {0x00a76e, 0x00a76e},
+ {0x00a779, 0x00a779},
+ {0x00a77b, 0x00a77b},
+ {0x00a77d, 0x00a77e},
+ {0x00a780, 0x00a780},
+ {0x00a782, 0x00a782},
+ {0x00a784, 0x00a784},
+ {0x00a786, 0x00a786},
+ {0x00a78b, 0x00a78b},
+ {0x00a78d, 0x00a78d},
+ {0x00a790, 0x00a790},
+ {0x00a792, 0x00a792},
+ {0x00a796, 0x00a796},
+ {0x00a798, 0x00a798},
+ {0x00a79a, 0x00a79a},
+ {0x00a79c, 0x00a79c},
+ {0x00a79e, 0x00a79e},
+ {0x00a7a0, 0x00a7a0},
+ {0x00a7a2, 0x00a7a2},
+ {0x00a7a4, 0x00a7a4},
+ {0x00a7a6, 0x00a7a6},
+ {0x00a7a8, 0x00a7a8},
+ {0x00a7aa, 0x00a7ae},
+ {0x00a7b0, 0x00a7b4},
+ {0x00a7b6, 0x00a7b6},
+ {0x00a7b8, 0x00a7b8},
+ {0x00a7ba, 0x00a7ba},
+ {0x00a7bc, 0x00a7bc},
+ {0x00a7be, 0x00a7be},
+ {0x00a7c0, 0x00a7c0},
+ {0x00a7c2, 0x00a7c2},
+ {0x00a7c4, 0x00a7c7},
+ {0x00a7c9, 0x00a7c9},
+ {0x00a7d0, 0x00a7d0},
+ {0x00a7d6, 0x00a7d6},
+ {0x00a7d8, 0x00a7d8},
+ {0x00a7f5, 0x00a7f5},
+ {0x00ff21, 0x00ff3a},
+ {0x010400, 0x010427},
+ {0x0104b0, 0x0104d3},
+ {0x010570, 0x01057a},
+ {0x01057c, 0x01058a},
+ {0x01058c, 0x010592},
+ {0x010594, 0x010595},
+ {0x010c80, 0x010cb2},
+ {0x0118a0, 0x0118bf},
+ {0x016e40, 0x016e5f},
+ {0x01d400, 0x01d419},
+ {0x01d434, 0x01d44d},
+ {0x01d468, 0x01d481},
+ {0x01d49c, 0x01d49c},
+ {0x01d49e, 0x01d49f},
+ {0x01d4a2, 0x01d4a2},
+ {0x01d4a5, 0x01d4a6},
+ {0x01d4a9, 0x01d4ac},
+ {0x01d4ae, 0x01d4b5},
+ {0x01d4d0, 0x01d4e9},
+ {0x01d504, 0x01d505},
+ {0x01d507, 0x01d50a},
+ {0x01d50d, 0x01d514},
+ {0x01d516, 0x01d51c},
+ {0x01d538, 0x01d539},
+ {0x01d53b, 0x01d53e},
+ {0x01d540, 0x01d544},
+ {0x01d546, 0x01d546},
+ {0x01d54a, 0x01d550},
+ {0x01d56c, 0x01d585},
+ {0x01d5a0, 0x01d5b9},
+ {0x01d5d4, 0x01d5ed},
+ {0x01d608, 0x01d621},
+ {0x01d63c, 0x01d655},
+ {0x01d670, 0x01d689},
+ {0x01d6a8, 0x01d6c0},
+ {0x01d6e2, 0x01d6fa},
+ {0x01d71c, 0x01d734},
+ {0x01d756, 0x01d76e},
+ {0x01d790, 0x01d7a8},
+ {0x01d7ca, 0x01d7ca},
+ {0x01e900, 0x01e921},
+ {0x01f130, 0x01f149},
+ {0x01f150, 0x01f169},
+ {0x01f170, 0x01f189},
+};
+
+/* table of Unicode codepoint ranges of Case_Ignorable characters */
+static const pg_unicode_range unicode_case_ignorable[491] =
+{
+ {0x000027, 0x000027},
+ {0x00002e, 0x00002e},
+ {0x00003a, 0x00003a},
+ {0x00005e, 0x00005e},
+ {0x000060, 0x000060},
+ {0x0000a8, 0x0000a8},
+ {0x0000ad, 0x0000ad},
+ {0x0000af, 0x0000af},
+ {0x0000b4, 0x0000b4},
+ {0x0000b7, 0x0000b7},
+ {0x0000b8, 0x0000b8},
+ {0x0002b0, 0x0002c1},
+ {0x0002c2, 0x0002c5},
+ {0x0002c6, 0x0002d1},
+ {0x0002d2, 0x0002df},
+ {0x0002e0, 0x0002e4},
+ {0x0002e5, 0x0002eb},
+ {0x0002ec, 0x0002ec},
+ {0x0002ed, 0x0002ed},
+ {0x0002ee, 0x0002ee},
+ {0x0002ef, 0x0002ff},
+ {0x000300, 0x00036f},
+ {0x000374, 0x000374},
+ {0x000375, 0x000375},
+ {0x00037a, 0x00037a},
+ {0x000384, 0x000385},
+ {0x000387, 0x000387},
+ {0x000483, 0x000487},
+ {0x000488, 0x000489},
+ {0x000559, 0x000559},
+ {0x00055f, 0x00055f},
+ {0x000591, 0x0005bd},
+ {0x0005bf, 0x0005bf},
+ {0x0005c1, 0x0005c2},
+ {0x0005c4, 0x0005c5},
+ {0x0005c7, 0x0005c7},
+ {0x0005f4, 0x0005f4},
+ {0x000600, 0x000605},
+ {0x000610, 0x00061a},
+ {0x00061c, 0x00061c},
+ {0x000640, 0x000640},
+ {0x00064b, 0x00065f},
+ {0x000670, 0x000670},
+ {0x0006d6, 0x0006dc},
+ {0x0006dd, 0x0006dd},
+ {0x0006df, 0x0006e4},
+ {0x0006e5, 0x0006e6},
+ {0x0006e7, 0x0006e8},
+ {0x0006ea, 0x0006ed},
+ {0x00070f, 0x00070f},
+ {0x000711, 0x000711},
+ {0x000730, 0x00074a},
+ {0x0007a6, 0x0007b0},
+ {0x0007eb, 0x0007f3},
+ {0x0007f4, 0x0007f5},
+ {0x0007fa, 0x0007fa},
+ {0x0007fd, 0x0007fd},
+ {0x000816, 0x000819},
+ {0x00081a, 0x00081a},
+ {0x00081b, 0x000823},
+ {0x000824, 0x000824},
+ {0x000825, 0x000827},
+ {0x000828, 0x000828},
+ {0x000829, 0x00082d},
+ {0x000859, 0x00085b},
+ {0x000888, 0x000888},
+ {0x000890, 0x000891},
+ {0x000898, 0x00089f},
+ {0x0008c9, 0x0008c9},
+ {0x0008ca, 0x0008e1},
+ {0x0008e2, 0x0008e2},
+ {0x0008e3, 0x000902},
+ {0x00093a, 0x00093a},
+ {0x00093c, 0x00093c},
+ {0x000941, 0x000948},
+ {0x00094d, 0x00094d},
+ {0x000951, 0x000957},
+ {0x000962, 0x000963},
+ {0x000971, 0x000971},
+ {0x000981, 0x000981},
+ {0x0009bc, 0x0009bc},
+ {0x0009c1, 0x0009c4},
+ {0x0009cd, 0x0009cd},
+ {0x0009e2, 0x0009e3},
+ {0x0009fe, 0x0009fe},
+ {0x000a01, 0x000a02},
+ {0x000a3c, 0x000a3c},
+ {0x000a41, 0x000a42},
+ {0x000a47, 0x000a48},
+ {0x000a4b, 0x000a4d},
+ {0x000a51, 0x000a51},
+ {0x000a70, 0x000a71},
+ {0x000a75, 0x000a75},
+ {0x000a81, 0x000a82},
+ {0x000abc, 0x000abc},
+ {0x000ac1, 0x000ac5},
+ {0x000ac7, 0x000ac8},
+ {0x000acd, 0x000acd},
+ {0x000ae2, 0x000ae3},
+ {0x000afa, 0x000aff},
+ {0x000b01, 0x000b01},
+ {0x000b3c, 0x000b3c},
+ {0x000b3f, 0x000b3f},
+ {0x000b41, 0x000b44},
+ {0x000b4d, 0x000b4d},
+ {0x000b55, 0x000b56},
+ {0x000b62, 0x000b63},
+ {0x000b82, 0x000b82},
+ {0x000bc0, 0x000bc0},
+ {0x000bcd, 0x000bcd},
+ {0x000c00, 0x000c00},
+ {0x000c04, 0x000c04},
+ {0x000c3c, 0x000c3c},
+ {0x000c3e, 0x000c40},
+ {0x000c46, 0x000c48},
+ {0x000c4a, 0x000c4d},
+ {0x000c55, 0x000c56},
+ {0x000c62, 0x000c63},
+ {0x000c81, 0x000c81},
+ {0x000cbc, 0x000cbc},
+ {0x000cbf, 0x000cbf},
+ {0x000cc6, 0x000cc6},
+ {0x000ccc, 0x000ccd},
+ {0x000ce2, 0x000ce3},
+ {0x000d00, 0x000d01},
+ {0x000d3b, 0x000d3c},
+ {0x000d41, 0x000d44},
+ {0x000d4d, 0x000d4d},
+ {0x000d62, 0x000d63},
+ {0x000d81, 0x000d81},
+ {0x000dca, 0x000dca},
+ {0x000dd2, 0x000dd4},
+ {0x000dd6, 0x000dd6},
+ {0x000e31, 0x000e31},
+ {0x000e34, 0x000e3a},
+ {0x000e46, 0x000e46},
+ {0x000e47, 0x000e4e},
+ {0x000eb1, 0x000eb1},
+ {0x000eb4, 0x000ebc},
+ {0x000ec6, 0x000ec6},
+ {0x000ec8, 0x000ece},
+ {0x000f18, 0x000f19},
+ {0x000f35, 0x000f35},
+ {0x000f37, 0x000f37},
+ {0x000f39, 0x000f39},
+ {0x000f71, 0x000f7e},
+ {0x000f80, 0x000f84},
+ {0x000f86, 0x000f87},
+ {0x000f8d, 0x000f97},
+ {0x000f99, 0x000fbc},
+ {0x000fc6, 0x000fc6},
+ {0x00102d, 0x001030},
+ {0x001032, 0x001037},
+ {0x001039, 0x00103a},
+ {0x00103d, 0x00103e},
+ {0x001058, 0x001059},
+ {0x00105e, 0x001060},
+ {0x001071, 0x001074},
+ {0x001082, 0x001082},
+ {0x001085, 0x001086},
+ {0x00108d, 0x00108d},
+ {0x00109d, 0x00109d},
+ {0x0010fc, 0x0010fc},
+ {0x00135d, 0x00135f},
+ {0x001712, 0x001714},
+ {0x001732, 0x001733},
+ {0x001752, 0x001753},
+ {0x001772, 0x001773},
+ {0x0017b4, 0x0017b5},
+ {0x0017b7, 0x0017bd},
+ {0x0017c6, 0x0017c6},
+ {0x0017c9, 0x0017d3},
+ {0x0017d7, 0x0017d7},
+ {0x0017dd, 0x0017dd},
+ {0x00180b, 0x00180d},
+ {0x00180e, 0x00180e},
+ {0x00180f, 0x00180f},
+ {0x001843, 0x001843},
+ {0x001885, 0x001886},
+ {0x0018a9, 0x0018a9},
+ {0x001920, 0x001922},
+ {0x001927, 0x001928},
+ {0x001932, 0x001932},
+ {0x001939, 0x00193b},
+ {0x001a17, 0x001a18},
+ {0x001a1b, 0x001a1b},
+ {0x001a56, 0x001a56},
+ {0x001a58, 0x001a5e},
+ {0x001a60, 0x001a60},
+ {0x001a62, 0x001a62},
+ {0x001a65, 0x001a6c},
+ {0x001a73, 0x001a7c},
+ {0x001a7f, 0x001a7f},
+ {0x001aa7, 0x001aa7},
+ {0x001ab0, 0x001abd},
+ {0x001abe, 0x001abe},
+ {0x001abf, 0x001ace},
+ {0x001b00, 0x001b03},
+ {0x001b34, 0x001b34},
+ {0x001b36, 0x001b3a},
+ {0x001b3c, 0x001b3c},
+ {0x001b42, 0x001b42},
+ {0x001b6b, 0x001b73},
+ {0x001b80, 0x001b81},
+ {0x001ba2, 0x001ba5},
+ {0x001ba8, 0x001ba9},
+ {0x001bab, 0x001bad},
+ {0x001be6, 0x001be6},
+ {0x001be8, 0x001be9},
+ {0x001bed, 0x001bed},
+ {0x001bef, 0x001bf1},
+ {0x001c2c, 0x001c33},
+ {0x001c36, 0x001c37},
+ {0x001c78, 0x001c7d},
+ {0x001cd0, 0x001cd2},
+ {0x001cd4, 0x001ce0},
+ {0x001ce2, 0x001ce8},
+ {0x001ced, 0x001ced},
+ {0x001cf4, 0x001cf4},
+ {0x001cf8, 0x001cf9},
+ {0x001d2c, 0x001d6a},
+ {0x001d78, 0x001d78},
+ {0x001d9b, 0x001dbf},
+ {0x001dc0, 0x001dff},
+ {0x001fbd, 0x001fbd},
+ {0x001fbf, 0x001fc1},
+ {0x001fcd, 0x001fcf},
+ {0x001fdd, 0x001fdf},
+ {0x001fed, 0x001fef},
+ {0x001ffd, 0x001ffe},
+ {0x00200b, 0x00200f},
+ {0x002018, 0x002018},
+ {0x002019, 0x002019},
+ {0x002024, 0x002024},
+ {0x002027, 0x002027},
+ {0x00202a, 0x00202e},
+ {0x002060, 0x002064},
+ {0x002066, 0x00206f},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x0020d0, 0x0020dc},
+ {0x0020dd, 0x0020e0},
+ {0x0020e1, 0x0020e1},
+ {0x0020e2, 0x0020e4},
+ {0x0020e5, 0x0020f0},
+ {0x002c7c, 0x002c7d},
+ {0x002cef, 0x002cf1},
+ {0x002d6f, 0x002d6f},
+ {0x002d7f, 0x002d7f},
+ {0x002de0, 0x002dff},
+ {0x002e2f, 0x002e2f},
+ {0x003005, 0x003005},
+ {0x00302a, 0x00302d},
+ {0x003031, 0x003035},
+ {0x00303b, 0x00303b},
+ {0x003099, 0x00309a},
+ {0x00309b, 0x00309c},
+ {0x00309d, 0x00309e},
+ {0x0030fc, 0x0030fe},
+ {0x00a015, 0x00a015},
+ {0x00a4f8, 0x00a4fd},
+ {0x00a60c, 0x00a60c},
+ {0x00a66f, 0x00a66f},
+ {0x00a670, 0x00a672},
+ {0x00a674, 0x00a67d},
+ {0x00a67f, 0x00a67f},
+ {0x00a69c, 0x00a69d},
+ {0x00a69e, 0x00a69f},
+ {0x00a6f0, 0x00a6f1},
+ {0x00a700, 0x00a716},
+ {0x00a717, 0x00a71f},
+ {0x00a720, 0x00a721},
+ {0x00a770, 0x00a770},
+ {0x00a788, 0x00a788},
+ {0x00a789, 0x00a78a},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a802, 0x00a802},
+ {0x00a806, 0x00a806},
+ {0x00a80b, 0x00a80b},
+ {0x00a825, 0x00a826},
+ {0x00a82c, 0x00a82c},
+ {0x00a8c4, 0x00a8c5},
+ {0x00a8e0, 0x00a8f1},
+ {0x00a8ff, 0x00a8ff},
+ {0x00a926, 0x00a92d},
+ {0x00a947, 0x00a951},
+ {0x00a980, 0x00a982},
+ {0x00a9b3, 0x00a9b3},
+ {0x00a9b6, 0x00a9b9},
+ {0x00a9bc, 0x00a9bd},
+ {0x00a9cf, 0x00a9cf},
+ {0x00a9e5, 0x00a9e5},
+ {0x00a9e6, 0x00a9e6},
+ {0x00aa29, 0x00aa2e},
+ {0x00aa31, 0x00aa32},
+ {0x00aa35, 0x00aa36},
+ {0x00aa43, 0x00aa43},
+ {0x00aa4c, 0x00aa4c},
+ {0x00aa70, 0x00aa70},
+ {0x00aa7c, 0x00aa7c},
+ {0x00aab0, 0x00aab0},
+ {0x00aab2, 0x00aab4},
+ {0x00aab7, 0x00aab8},
+ {0x00aabe, 0x00aabf},
+ {0x00aac1, 0x00aac1},
+ {0x00aadd, 0x00aadd},
+ {0x00aaec, 0x00aaed},
+ {0x00aaf3, 0x00aaf4},
+ {0x00aaf6, 0x00aaf6},
+ {0x00ab5b, 0x00ab5b},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab69, 0x00ab69},
+ {0x00ab6a, 0x00ab6b},
+ {0x00abe5, 0x00abe5},
+ {0x00abe8, 0x00abe8},
+ {0x00abed, 0x00abed},
+ {0x00fb1e, 0x00fb1e},
+ {0x00fbb2, 0x00fbc2},
+ {0x00fe00, 0x00fe0f},
+ {0x00fe13, 0x00fe13},
+ {0x00fe20, 0x00fe2f},
+ {0x00fe52, 0x00fe52},
+ {0x00fe55, 0x00fe55},
+ {0x00feff, 0x00feff},
+ {0x00ff07, 0x00ff07},
+ {0x00ff0e, 0x00ff0e},
+ {0x00ff1a, 0x00ff1a},
+ {0x00ff3e, 0x00ff3e},
+ {0x00ff40, 0x00ff40},
+ {0x00ff70, 0x00ff70},
+ {0x00ff9e, 0x00ff9f},
+ {0x00ffe3, 0x00ffe3},
+ {0x00fff9, 0x00fffb},
+ {0x0101fd, 0x0101fd},
+ {0x0102e0, 0x0102e0},
+ {0x010376, 0x01037a},
+ {0x010780, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010a01, 0x010a03},
+ {0x010a05, 0x010a06},
+ {0x010a0c, 0x010a0f},
+ {0x010a38, 0x010a3a},
+ {0x010a3f, 0x010a3f},
+ {0x010ae5, 0x010ae6},
+ {0x010d24, 0x010d27},
+ {0x010eab, 0x010eac},
+ {0x010efd, 0x010eff},
+ {0x010f46, 0x010f50},
+ {0x010f82, 0x010f85},
+ {0x011001, 0x011001},
+ {0x011038, 0x011046},
+ {0x011070, 0x011070},
+ {0x011073, 0x011074},
+ {0x01107f, 0x011081},
+ {0x0110b3, 0x0110b6},
+ {0x0110b9, 0x0110ba},
+ {0x0110bd, 0x0110bd},
+ {0x0110c2, 0x0110c2},
+ {0x0110cd, 0x0110cd},
+ {0x011100, 0x011102},
+ {0x011127, 0x01112b},
+ {0x01112d, 0x011134},
+ {0x011173, 0x011173},
+ {0x011180, 0x011181},
+ {0x0111b6, 0x0111be},
+ {0x0111c9, 0x0111cc},
+ {0x0111cf, 0x0111cf},
+ {0x01122f, 0x011231},
+ {0x011234, 0x011234},
+ {0x011236, 0x011237},
+ {0x01123e, 0x01123e},
+ {0x011241, 0x011241},
+ {0x0112df, 0x0112df},
+ {0x0112e3, 0x0112ea},
+ {0x011300, 0x011301},
+ {0x01133b, 0x01133c},
+ {0x011340, 0x011340},
+ {0x011366, 0x01136c},
+ {0x011370, 0x011374},
+ {0x011438, 0x01143f},
+ {0x011442, 0x011444},
+ {0x011446, 0x011446},
+ {0x01145e, 0x01145e},
+ {0x0114b3, 0x0114b8},
+ {0x0114ba, 0x0114ba},
+ {0x0114bf, 0x0114c0},
+ {0x0114c2, 0x0114c3},
+ {0x0115b2, 0x0115b5},
+ {0x0115bc, 0x0115bd},
+ {0x0115bf, 0x0115c0},
+ {0x0115dc, 0x0115dd},
+ {0x011633, 0x01163a},
+ {0x01163d, 0x01163d},
+ {0x01163f, 0x011640},
+ {0x0116ab, 0x0116ab},
+ {0x0116ad, 0x0116ad},
+ {0x0116b0, 0x0116b5},
+ {0x0116b7, 0x0116b7},
+ {0x01171d, 0x01171f},
+ {0x011722, 0x011725},
+ {0x011727, 0x01172b},
+ {0x01182f, 0x011837},
+ {0x011839, 0x01183a},
+ {0x01193b, 0x01193c},
+ {0x01193e, 0x01193e},
+ {0x011943, 0x011943},
+ {0x0119d4, 0x0119d7},
+ {0x0119da, 0x0119db},
+ {0x0119e0, 0x0119e0},
+ {0x011a01, 0x011a0a},
+ {0x011a33, 0x011a38},
+ {0x011a3b, 0x011a3e},
+ {0x011a47, 0x011a47},
+ {0x011a51, 0x011a56},
+ {0x011a59, 0x011a5b},
+ {0x011a8a, 0x011a96},
+ {0x011a98, 0x011a99},
+ {0x011c30, 0x011c36},
+ {0x011c38, 0x011c3d},
+ {0x011c3f, 0x011c3f},
+ {0x011c92, 0x011ca7},
+ {0x011caa, 0x011cb0},
+ {0x011cb2, 0x011cb3},
+ {0x011cb5, 0x011cb6},
+ {0x011d31, 0x011d36},
+ {0x011d3a, 0x011d3a},
+ {0x011d3c, 0x011d3d},
+ {0x011d3f, 0x011d45},
+ {0x011d47, 0x011d47},
+ {0x011d90, 0x011d91},
+ {0x011d95, 0x011d95},
+ {0x011d97, 0x011d97},
+ {0x011ef3, 0x011ef4},
+ {0x011f00, 0x011f01},
+ {0x011f36, 0x011f3a},
+ {0x011f40, 0x011f40},
+ {0x011f42, 0x011f42},
+ {0x013430, 0x01343f},
+ {0x013440, 0x013440},
+ {0x013447, 0x013455},
+ {0x016af0, 0x016af4},
+ {0x016b30, 0x016b36},
+ {0x016b40, 0x016b43},
+ {0x016f4f, 0x016f4f},
+ {0x016f8f, 0x016f92},
+ {0x016f93, 0x016f9f},
+ {0x016fe0, 0x016fe1},
+ {0x016fe3, 0x016fe3},
+ {0x016fe4, 0x016fe4},
+ {0x01aff0, 0x01aff3},
+ {0x01aff5, 0x01affb},
+ {0x01affd, 0x01affe},
+ {0x01bc9d, 0x01bc9e},
+ {0x01bca0, 0x01bca3},
+ {0x01cf00, 0x01cf2d},
+ {0x01cf30, 0x01cf46},
+ {0x01d167, 0x01d169},
+ {0x01d173, 0x01d17a},
+ {0x01d17b, 0x01d182},
+ {0x01d185, 0x01d18b},
+ {0x01d1aa, 0x01d1ad},
+ {0x01d242, 0x01d244},
+ {0x01da00, 0x01da36},
+ {0x01da3b, 0x01da6c},
+ {0x01da75, 0x01da75},
+ {0x01da84, 0x01da84},
+ {0x01da9b, 0x01da9f},
+ {0x01daa1, 0x01daaf},
+ {0x01e000, 0x01e006},
+ {0x01e008, 0x01e018},
+ {0x01e01b, 0x01e021},
+ {0x01e023, 0x01e024},
+ {0x01e026, 0x01e02a},
+ {0x01e030, 0x01e06d},
+ {0x01e08f, 0x01e08f},
+ {0x01e130, 0x01e136},
+ {0x01e137, 0x01e13d},
+ {0x01e2ae, 0x01e2ae},
+ {0x01e2ec, 0x01e2ef},
+ {0x01e4eb, 0x01e4eb},
+ {0x01e4ec, 0x01e4ef},
+ {0x01e8d0, 0x01e8d6},
+ {0x01e944, 0x01e94a},
+ {0x01e94b, 0x01e94b},
+ {0x01f3fb, 0x01f3ff},
+ {0x0e0001, 0x0e0001},
+ {0x0e0020, 0x0e007f},
+ {0x0e0100, 0x0e01ef},
+};
+
+/* table of Unicode codepoint ranges of White_Space characters */
+static const pg_unicode_range unicode_white_space[11] =
+{
+ {0x000009, 0x00000d},
+ {0x000020, 0x000020},
+ {0x000085, 0x000085},
+ {0x0000a0, 0x0000a0},
+ {0x001680, 0x001680},
+ {0x002000, 0x00200a},
+ {0x002028, 0x002028},
+ {0x002029, 0x002029},
+ {0x00202f, 0x00202f},
+ {0x00205f, 0x00205f},
+ {0x003000, 0x003000},
+};
+
+/* table of Unicode codepoint ranges of Hex_Digit characters */
+static const pg_unicode_range unicode_hex_digit[6] =
+{
+ {0x000030, 0x000039},
+ {0x000041, 0x000046},
+ {0x000061, 0x000066},
+ {0x00ff10, 0x00ff19},
+ {0x00ff21, 0x00ff26},
+ {0x00ff41, 0x00ff46},
+};
+
+/* table of Unicode codepoint ranges of Join_Control characters */
+static const pg_unicode_range unicode_join_control[1] =
+{
+ {0x00200c, 0x00200d},
};
--
2.34.1
[text/x-patch] v19-0003-Add-unicode-case-mapping-tables-and-functions.patch (315.7K, ../../[email protected]/4-v19-0003-Add-unicode-case-mapping-tables-and-functions.patch)
download | inline diff:
From 697ac94a873e46b015e00ed12d3c8864e1fafc4b Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 30 Oct 2023 17:38:54 -0700
Subject: [PATCH v19 3/6] Add unicode case mapping tables and functions.
---
src/common/Makefile | 1 +
src/common/meson.build | 1 +
src/common/unicode/Makefile | 15 +-
src/common/unicode/case_test.c | 100 +
.../unicode/generate-unicode_case_table.pl | 287 ++
src/common/unicode/meson.build | 33 +-
src/common/unicode_case.c | 344 ++
src/common/wchar.c | 4 +-
src/include/common/unicode_case.h | 32 +
src/include/common/unicode_case_table.h | 3183 +++++++++++++++++
src/include/mb/pg_wchar.h | 15 +
11 files changed, 4009 insertions(+), 6 deletions(-)
create mode 100644 src/common/unicode/case_test.c
create mode 100644 src/common/unicode/generate-unicode_case_table.pl
create mode 100644 src/common/unicode_case.c
create mode 100644 src/include/common/unicode_case.h
create mode 100644 src/include/common/unicode_case_table.h
diff --git a/src/common/Makefile b/src/common/Makefile
index 2ba5069dca..3d83299432 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -78,6 +78,7 @@ OBJS_COMMON = \
scram-common.o \
string.o \
stringinfo.o \
+ unicode_case.o \
unicode_category.o \
unicode_norm.o \
username.o \
diff --git a/src/common/meson.build b/src/common/meson.build
index 4eb16024cb..de68e408fa 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -32,6 +32,7 @@ common_sources = files(
'scram-common.c',
'string.c',
'stringinfo.c',
+ 'unicode_case.c',
'unicode_category.c',
'unicode_norm.c',
'username.c',
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index 27f0408d8b..6c3a275772 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -21,20 +21,24 @@ CPPFLAGS += $(ICU_CFLAGS)
# By default, do nothing.
all:
-update-unicode: unicode_category_table.h unicode_east_asian_fw_table.h unicode_nonspacing_table.h unicode_norm_hashfunc.h unicode_norm_table.h unicode_normprops_table.h unicode_version.h
+update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian_fw_table.h unicode_nonspacing_table.h unicode_norm_hashfunc.h unicode_norm_table.h unicode_normprops_table.h unicode_version.h
mv $^ $(top_srcdir)/src/include/common/
+ $(MAKE) case-check
$(MAKE) category-check
$(MAKE) normalization-check
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
$(PERL) $< --version $(UNICODE_VERSION)
+unicode_case_table.h: generate-unicode_case_table.pl UnicodeData.txt
+ $(PERL) $<
+
unicode_category_table.h: generate-unicode_category_table.pl DerivedCoreProperties.txt PropList.txt UnicodeData.txt
$(PERL) $<
@@ -55,12 +59,17 @@ unicode_normprops_table.h: generate-unicode_normprops_table.pl DerivedNormalizat
$(PERL) $^ >$@
# Test suite
+case-check: case_test
+ ./case_test
+
category-check: category_test
./category_test
normalization-check: norm_test
./norm_test
+case_test: case_test.o ../unicode_case.o | submake-common
+
category_test: category_test.o ../unicode_category.o | submake-common
norm_test: norm_test.o ../unicode_norm.o | submake-common
@@ -82,4 +91,4 @@ clean:
rm -f $(OBJS) category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/case_test.c b/src/common/unicode/case_test.c
new file mode 100644
index 0000000000..7b82d5e0aa
--- /dev/null
+++ b/src/common/unicode/case_test.c
@@ -0,0 +1,100 @@
+/*-------------------------------------------------------------------------
+ * case_test.c
+ * Program to test Unicode case mapping functions.
+ *
+ * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/unicode/case_test.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres_fe.h"
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wctype.h>
+
+#ifdef USE_ICU
+#include <unicode/uchar.h>
+#endif
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
+#include "common/unicode_version.h"
+
+#ifdef USE_ICU
+
+static void
+icu_test_simple(pg_wchar code)
+{
+ pg_wchar lower = unicode_lowercase_simple(code);
+ pg_wchar title = unicode_titlecase_simple(code);
+ pg_wchar upper = unicode_uppercase_simple(code);
+ pg_wchar iculower = u_tolower(code);
+ pg_wchar icutitle = u_totitle(code);
+ pg_wchar icuupper = u_toupper(code);
+
+ if (lower != iculower || title != icutitle || upper != icuupper)
+ {
+ printf("case_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("case_test: Postgres lower/title/upper: 0x%06x/0x%06x/0x%06x\n",
+ lower, title, upper);
+ printf("case_test: ICU lower/title/upper: 0x%06x/0x%06x/0x%06x\n",
+ iculower, icutitle, icuupper);
+ printf("\n");
+ exit(1);
+ }
+}
+
+static void
+test_icu(void)
+{
+ int successful = 0;
+ int skipped_mismatch = 0;
+
+ for (pg_wchar code = 0; code <= 0x10ffff; code++)
+ {
+ pg_unicode_category category = unicode_category(code);
+
+ if (category != PG_U_UNASSIGNED)
+ {
+ uint8_t icu_category = u_charType(code);
+
+ if (icu_category == PG_U_UNASSIGNED)
+ {
+ skipped_mismatch++;
+ continue;
+ }
+
+ icu_test_simple(code);
+ successful++;
+ }
+ }
+
+ if (skipped_mismatch > 0)
+ printf("case_test: skipped %d codepoints unassigned in ICU due to Unicode version mismatch\n",
+ skipped_mismatch);
+
+ printf("case_test: ICU simple mapping test: %d codepoints successful\n",
+ successful);
+}
+#endif
+
+/*
+ * Exhaustively compare case mappings with the results from libc and ICU.
+ */
+int
+main(int argc, char **argv)
+{
+ printf("case_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
+#ifdef USE_ICU
+ printf("case_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
+ test_icu();
+#else
+ printf("case_test: ICU not available; skipping\n");
+#endif
+
+ exit(0);
+}
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
new file mode 100644
index 0000000000..02da4b682f
--- /dev/null
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -0,0 +1,287 @@
+#!/usr/bin/perl
+#
+# Generate Unicode character case mappings. Does not include tailoring
+# or locale-specific mappings.
+#
+# Input: SpecialCasing.txt UnicodeData.txt
+# Output: unicode_case_table.h
+#
+# Copyright (c) 2000-2023, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+use FindBin;
+use lib "$FindBin::RealBin/../../tools/";
+
+my $output_path = '.';
+
+GetOptions('outdir:s' => \$output_path);
+
+my $output_table_file = "$output_path/unicode_case_table.h";
+
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
+my $FH;
+
+my %simple = ();
+
+open($FH, '<', "$output_path/UnicodeData.txt")
+ or die "Could not open $output_path/UnicodeData.txt: $!.";
+while (my $line = <$FH>)
+{
+ my @elts = split(';', $line);
+ my $code = hex($elts[0]);
+ my $simple_uppercase = hex($elts[12] =~ s/^\s+|\s+$//rg);
+ my $simple_lowercase = hex($elts[13] =~ s/^\s+|\s+$//rg);
+ my $simple_titlecase = hex($elts[14] =~ s/^\s+|\s+$//rg);
+
+ die "codepoint $code out of range" if $code > 0x10FFFF;
+ die "Simple_Lowercase $code out of range" if $simple_lowercase > 0x10FFFF;
+ die "Simple_Titlecase $code out of range" if $simple_titlecase > 0x10FFFF;
+ die "Simple_Uppercase $code out of range" if $simple_uppercase > 0x10FFFF;
+
+ if ($simple_lowercase || $simple_titlecase || $simple_uppercase)
+ {
+ $simple{$code} = {
+ Simple_Lowercase => ($simple_lowercase || $code),
+ Simple_Titlecase => ($simple_titlecase || $code),
+ Simple_Uppercase => ($simple_uppercase || $code)
+ };
+ }
+}
+close $FH;
+
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
+# Start writing out the output files
+open my $OT, '>', $output_table_file
+ or die "Could not open output file $output_table_file: $!\n";
+
+# determine size of array given that codepoints <= 0x80 are dense and
+# the rest of the entries are sparse
+my $num_simple = 0x80;
+foreach my $code (sort { $a <=> $b } (keys %simple))
+{
+ $num_simple++ unless $code < 0x80;
+}
+
+my $num_special = scalar(keys %special) + 1;
+
+print $OT <<"EOS";
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case_table.h
+ * Case mapping and information table.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/common/unicode_case_table.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * File auto-generated by src/common/unicode/generate-unicode_case_table.pl,
+ * do not edit. There is deliberately not an #ifndef PG_UNICODE_CASE_TABLE_H
+ * here.
+ */
+
+#include "common/unicode_case.h"
+#include "mb/pg_wchar.h"
+
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
+typedef enum
+{
+ CaseLower = 0,
+ CaseTitle = 1,
+ CaseUpper = 2,
+ NCaseKind
+} CaseKind;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
+} pg_case_map;
+
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
+/*
+ * Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
+ * sparse for higher codepoints (requiring scan or binary search).
+ */
+static const pg_case_map case_map[$num_simple] =
+{
+EOS
+
+printf $OT "\t/* begin dense entries for codepoints < 0x80 */\n";
+for (my $code = 0; $code < 0x80; $code++)
+{
+ my $lc = ($simple{$code}{Simple_Lowercase} || $code);
+ my $tc = ($simple{$code}{Simple_Titlecase} || $code);
+ my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
+ printf $OT
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
+ $code, $lc, $tc, $uc;
+}
+printf $OT "\n";
+
+printf $OT "\t/* begin sparse entries for codepoints >= 0x80 */\n";
+foreach my $code (sort { $a <=> $b } (keys %simple))
+{
+ next unless $code >= 0x80; # already output above
+
+ my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
+ printf $OT
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
+ $code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
+ $map->{Simple_Uppercase}, $special_case;
+}
+print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index d7190bb8ca..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -24,6 +24,16 @@ endforeach
update_unicode_targets = []
+update_unicode_targets += \
+ custom_target('unicode_case_table.h',
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
+ output: ['unicode_case_table.h'],
+ command: [
+ perl, files('generate-unicode_case_table.pl'),
+ '--outdir', '@OUTDIR@', '@INPUT@'],
+ build_by_default: false,
+ )
+
update_unicode_targets += \
custom_target('unicode_category_table.h',
input: [unicode_data['UnicodeData.txt'], unicode_data['DerivedCoreProperties.txt'], unicode_data['PropList.txt']],
@@ -92,6 +102,17 @@ norm_test_table = custom_target('norm_test_table.h',
inc = include_directories('.')
+case_test = executable('case_test',
+ ['case_test.c'],
+ dependencies: [frontend_port_code, icu],
+ include_directories: inc,
+ link_with: [common_static, pgport_static],
+ build_by_default: false,
+ kwargs: default_bin_args + {
+ 'install': false,
+ }
+)
+
category_test = executable('category_test',
['category_test.c'],
dependencies: [frontend_port_code, icu],
@@ -116,6 +137,16 @@ norm_test = executable('norm_test',
update_unicode_dep = []
+if not meson.is_cross_build()
+ update_unicode_dep += custom_target('case_test.run',
+ output: 'case_test.run',
+ input: update_unicode_targets,
+ command: [case_test, UNICODE_VERSION],
+ build_by_default: false,
+ build_always_stale: true,
+ )
+endif
+
if not meson.is_cross_build()
update_unicode_dep += custom_target('category_test.run',
output: 'category_test.run',
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
new file mode 100644
index 0000000000..e6e6424bb3
--- /dev/null
+++ b/src/common/unicode_case.c
@@ -0,0 +1,344 @@
+/*-------------------------------------------------------------------------
+ * unicode_case.c
+ * Conversion to upper or lower case.
+ *
+ * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/unicode_case.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/unicode_case.h"
+#include "common/unicode_case_table.h"
+#include "common/unicode_category.h"
+#include "mb/pg_wchar.h"
+
+static const pg_case_map *find_case_map(pg_wchar ucs);
+static size_t convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
+ CaseKind top_casekind, bool real_titlecase, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
+
+pg_wchar
+unicode_lowercase_simple(pg_wchar code)
+{
+ const pg_case_map *map = find_case_map(code);
+
+ return map ? map->simplemap[CaseLower] : code;
+}
+
+pg_wchar
+unicode_titlecase_simple(pg_wchar code)
+{
+ const pg_case_map *map = find_case_map(code);
+
+ return map ? map->simplemap[CaseTitle] : code;
+}
+
+pg_wchar
+unicode_uppercase_simple(pg_wchar code)
+{
+ const pg_case_map *map = find_case_map(code);
+
+ return map ? map->simplemap[CaseUpper] : code;
+}
+
+/*
+ * unicode_strlower(), unicode_strtitle(), unicode_strupper()
+ *
+ * Convert case of src, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ */
+
+size_t
+unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool full)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseLower, false, full, NULL, NULL);
+}
+
+size_t
+unicode_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool real_titlecase, bool full, WordBoundaryNext wbnext, void *wbstate)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, real_titlecase, full, wbnext, wbstate);
+}
+
+size_t
+unicode_strupper(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool full)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, false, full, NULL, NULL);
+}
+
+/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
+ * Titlecasing requires knowledge about word boundaries, which is provided by
+ * a callback wbnext. The caller is expected to initialize and free the
+ * callback state wbstate. The callback should first return offset 0 for the
+ * first boundary, then the offset of each subsequent word boundary, then the
+ * total length of the string to indicate the final boundary. A word boundary
+ * is either the offset of the start of a word or the offset of the first
+ * character after a word completes.
+ *
+ * The titlecasing algorithm is as follows: for each word boundary, skip
+ * conversion until the first Cased character is found, and map it to
+ * titlecase. Then map the remaining characters to lowercase until the next
+ * word boundary is found. Other case conversions simply map all of the
+ * characters to the requested case, if a mapping exists.
+ *
+ * In most cases, mapping is a simple one-to-one conversion. But some special
+ * mappings exist which map one character to multiple code points, or have
+ * conditional mappings that may depend on context.
+ */
+static size_t
+convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
+ CaseKind top_casekind, bool real_titlecase, bool full,
+ WordBoundaryNext wbnext, void *wbstate)
+{
+ size_t srcoff = 0;
+ size_t result_len = 0;
+ size_t boundary = 0;
+ bool find_next_cased = true;
+ CaseKind casekind = top_casekind;
+
+ /* need word boundaries for titlecasing */
+ if (top_casekind == CaseTitle)
+ boundary = wbnext(wbstate);
+
+ while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
+ {
+ pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
+ int u1len = unicode_utf8len(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+
+ /*
+ * Titlecasing has two states: searching for the next Cased character;
+ * and searching for the next word boundary.
+ *
+ * While searching for the next Cased character, just copy the bytes
+ * from src without conversion, until we find the next Cased
+ * character, which is mapped to titlecase. While searching for the
+ * next word boundary, map each character to lowercase.
+ */
+ if (top_casekind == CaseTitle)
+ {
+ if (srcoff == boundary)
+ {
+ /* switch state to finding next Cased character */
+ find_next_cased = true;
+ boundary = wbnext(wbstate);
+ }
+
+ if (find_next_cased && pg_u_prop_cased(u1))
+ {
+ /* titlecase this character, then switch to lowercasing */
+ find_next_cased = false;
+ casekind = real_titlecase ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else if (!find_next_cased)
+ {
+ /* lowercase this character */
+ casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ else
+ {
+ /* copy from src without conversion */
+ casemap = NULL;
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Only a single special mapping per codepoint is currently supported.
+ * Unicode allows for multiple special mappings for a single
+ * codepoint, so we may have a reason to support that in the future.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
+ {
+ pg_wchar u2 = casemap->simplemap[casekind];
+ pg_wchar u2len = unicode_utf8len(u2);
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ else
+ {
+ /* no mapping; copy bytes from src */
+ if (result_len + u1len < dstsize)
+ memcpy(dst + result_len, src + srcoff, u1len);
+
+ result_len += u1len;
+ }
+
+ srcoff += u1len;
+ }
+
+ if (result_len < dstsize)
+ dst[result_len] = '\0';
+
+ return result_len;
+}
+
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
+/* find entry in simple case map, if any */
+static const pg_case_map *
+find_case_map(pg_wchar ucs)
+{
+ int min = 0;
+ int mid;
+ int max = lengthof(case_map) - 1;
+
+ /* all chars <= 0x80 are stored in array for fast lookup */
+ Assert(max >= 0x7f);
+ if (ucs < 0x80)
+ {
+ const pg_case_map *map = &case_map[ucs];
+
+ Assert(map->codepoint == ucs);
+ return map;
+ }
+
+ /* otherwise, binary search */
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (ucs > case_map[mid].codepoint)
+ min = mid + 1;
+ else if (ucs < case_map[mid].codepoint)
+ max = mid - 1;
+ else
+ return &case_map[mid];
+ }
+
+ return NULL;
+}
diff --git a/src/common/wchar.c b/src/common/wchar.c
index 7e7a7507d5..a238c0106c 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -477,8 +477,8 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
/*
- * Map a Unicode code point to UTF-8. utf8string must have 4 bytes of
- * space allocated.
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
*/
unsigned char *
unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
new file mode 100644
index 0000000000..d0815ecd5a
--- /dev/null
+++ b/src/include/common/unicode_case.h
@@ -0,0 +1,32 @@
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case.h
+ * Routines for converting character case.
+ *
+ * These definitions can be used by both frontend and backend code.
+ *
+ * Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * src/include/common/unicode_case.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef UNICODE_CASE_H
+#define UNICODE_CASE_H
+
+#include "mb/pg_wchar.h"
+
+typedef size_t (*WordBoundaryNext) (void *);
+
+pg_wchar unicode_lowercase_simple(pg_wchar ucs);
+pg_wchar unicode_titlecase_simple(pg_wchar ucs);
+pg_wchar unicode_uppercase_simple(pg_wchar ucs);
+size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
+ size_t srclen, bool full);
+size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
+ size_t srclen, bool real_titlecase, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
+size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
+ size_t srclen, bool full);
+
+#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
new file mode 100644
index 0000000000..081d4133b1
--- /dev/null
+++ b/src/include/common/unicode_case_table.h
@@ -0,0 +1,3183 @@
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case_table.h
+ * Case mapping and information table.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/common/unicode_case_table.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * File auto-generated by src/common/unicode/generate-unicode_case_table.pl,
+ * do not edit. There is deliberately not an #ifndef PG_UNICODE_CASE_TABLE_H
+ * here.
+ */
+
+#include "common/unicode_case.h"
+#include "mb/pg_wchar.h"
+
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
+typedef enum
+{
+ CaseLower = 0,
+ CaseTitle = 1,
+ CaseUpper = 2,
+ NCaseKind
+} CaseKind;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
+} pg_case_map;
+
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
+/*
+ * Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
+ * sparse for higher codepoints (requiring scan or binary search).
+ */
+static const pg_case_map case_map[3003] =
+{
+ /* begin dense entries for codepoints < 0x80 */
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
+
+ /* begin sparse entries for codepoints >= 0x80 */
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+};
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index fd91aefbcb..183451c896 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -560,6 +560,21 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Number of bytes needed to represent the given char in UTF8.
+ */
+static inline int
+unicode_utf8len(pg_wchar c)
+{
+ if (c <= 0x7F)
+ return 1;
+ else if (c <= 0x7FF)
+ return 2;
+ else if (c <= 0xFFFF)
+ return 3;
+ else
+ return 4;
+}
/*
* The functions in this list are exported by libpq, and we need to be sure
--
2.34.1
[text/x-patch] v19-0004-Catalog-changes-preparing-for-builtin-collation-.patch (48.5K, ../../[email protected]/5-v19-0004-Catalog-changes-preparing-for-builtin-collation-.patch)
download | inline diff:
From b0bb327e3071e39aa905ab6c8f557547a946725c Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Tue, 26 Dec 2023 13:32:48 -0800
Subject: [PATCH v19 4/6] Catalog changes preparing for builtin collation
provider.
daticulocale -> datlocale, colliculocale -> colllocale.
---
doc/src/sgml/bki.sgml | 2 +-
doc/src/sgml/catalogs.sgml | 8 +--
src/backend/catalog/pg_collation.c | 10 +--
src/backend/commands/collationcmds.c | 34 +++++-----
src/backend/commands/dbcommands.c | 68 +++++++++----------
src/backend/utils/adt/pg_locale.c | 4 +-
src/backend/utils/init/postinit.c | 12 ++--
src/bin/initdb/initdb.c | 32 ++++-----
src/bin/pg_dump/pg_dump.c | 56 ++++++++-------
src/bin/pg_upgrade/info.c | 31 ++++++---
src/bin/pg_upgrade/pg_upgrade.c | 34 +++++++---
src/bin/pg_upgrade/pg_upgrade.h | 2 +-
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 27 +++++---
src/bin/psql/describe.c | 20 ++++--
src/include/catalog/pg_collation.dat | 2 +-
src/include/catalog/pg_collation.h | 4 +-
src/include/catalog/pg_database.dat | 2 +-
src/include/catalog/pg_database.h | 2 +-
.../regress/expected/collate.icu.utf8.out | 4 +-
src/test/regress/expected/psql.out | 18 ++---
src/test/regress/sql/collate.icu.utf8.sql | 4 +-
21 files changed, 211 insertions(+), 165 deletions(-)
diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 315ba81951..3cd5bee7ff 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -186,7 +186,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE', datacl => '_null_' },
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE', datacl => '_null_' },
]
]]></programlisting>
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 880f717b10..734b1cf74f 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2422,10 +2422,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>colliculocale</structfield> <type>text</type>
+ <structfield>colllocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this collation object
+ Locale name for builtin or ICU provider
</para></entry>
</row>
@@ -3131,10 +3131,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>daticulocale</structfield> <type>text</type>
+ <structfield>datlocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this database
+ Locale name for builtin or ICU provider
</para></entry>
</row>
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 5c8ccb8b3b..7bad94f908 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -49,7 +49,7 @@ CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
@@ -68,7 +68,7 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colliculocale);
+ Assert((collcollate && collctype) || colllocale);
/*
* Make sure there is no existing collation of same name & encoding.
@@ -191,10 +191,10 @@ CollationCreate(const char *collname, Oid collnamespace,
values[Anum_pg_collation_collctype - 1] = CStringGetTextDatum(collctype);
else
nulls[Anum_pg_collation_collctype - 1] = true;
- if (colliculocale)
- values[Anum_pg_collation_colliculocale - 1] = CStringGetTextDatum(colliculocale);
+ if (colllocale)
+ values[Anum_pg_collation_colllocale - 1] = CStringGetTextDatum(colllocale);
else
- nulls[Anum_pg_collation_colliculocale - 1] = true;
+ nulls[Anum_pg_collation_colllocale - 1] = true;
if (collicurules)
values[Anum_pg_collation_collicurules - 1] = CStringGetTextDatum(collicurules);
else
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 58c059fdb7..27564e569a 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -68,7 +68,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colliculocale;
+ char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -159,11 +159,11 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
else
collctype = NULL;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colliculocale, &isnull);
+ datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colllocale, &isnull);
if (!isnull)
- colliculocale = TextDatumGetCString(datum);
+ colllocale = TextDatumGetCString(datum);
else
- colliculocale = NULL;
+ colllocale = NULL;
/*
* When the ICU locale comes from an existing collation, do not
@@ -196,7 +196,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collcollate = NULL;
collctype = NULL;
- colliculocale = NULL;
+ colllocale = NULL;
collicurules = NULL;
if (providerEl)
@@ -236,7 +236,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collctype = defGetString(localeEl);
}
else
- colliculocale = defGetString(localeEl);
+ colllocale = defGetString(localeEl);
}
if (lccollateEl)
@@ -261,7 +261,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
else if (collprovider == COLLPROVIDER_ICU)
{
- if (!colliculocale)
+ if (!colllocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("parameter \"%s\" must be specified",
@@ -273,20 +273,20 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
*/
if (!IsBinaryUpgrade)
{
- char *langtag = icu_language_tag(colliculocale,
+ char *langtag = icu_language_tag(colllocale,
icu_validation_level);
- if (langtag && strcmp(colliculocale, langtag) != 0)
+ if (langtag && strcmp(colllocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, colliculocale)));
+ langtag, colllocale)));
- colliculocale = langtag;
+ colllocale = langtag;
}
}
- icu_validate_locale(colliculocale);
+ icu_validate_locale(colllocale);
}
/*
@@ -334,7 +334,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colliculocale : collcollate);
+ collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
newoid = CollationCreate(collName,
collNamespace,
@@ -344,7 +344,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collencoding,
collcollate,
collctype,
- colliculocale,
+ colllocale,
collicurules,
collversion,
if_not_exists,
@@ -435,7 +435,7 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
/* cannot change from NULL to non-NULL or vice versa */
@@ -502,7 +502,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
provider == COLLPROVIDER_ICU ?
- Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ Anum_pg_database_datlocale : Anum_pg_database_datcollate);
locale = TextDatumGetCString(datum);
@@ -523,7 +523,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
Assert(provider != COLLPROVIDER_DEFAULT);
datum = SysCacheGetAttrNotNull(COLLOID, colltp,
provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
locale = TextDatumGetCString(datum);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index b1327de71e..d1de46e759 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -118,7 +118,7 @@ static bool get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion);
@@ -675,7 +675,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
int src_encoding = -1;
char *src_collate = NULL;
char *src_ctype = NULL;
- char *src_iculocale = NULL;
+ char *src_locale = NULL;
char *src_icurules = NULL;
char src_locprovider = '\0';
char *src_collversion = NULL;
@@ -713,7 +713,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dbiculocale = NULL;
+ char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -903,7 +903,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (dctype && dctype->arg)
dbctype = defGetString(dctype);
if (diculocale && diculocale->arg)
- dbiculocale = defGetString(diculocale);
+ dblocale = defGetString(diculocale);
if (dicurules && dicurules->arg)
dbicurules = defGetString(dicurules);
if (dlocprovider && dlocprovider->arg)
@@ -971,7 +971,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
&src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_allowconn, &src_hasloginevt,
&src_frozenxid, &src_minmxid, &src_deftablespace,
- &src_collate, &src_ctype, &src_iculocale, &src_icurules, &src_locprovider,
+ &src_collate, &src_ctype, &src_locale, &src_icurules, &src_locprovider,
&src_collversion))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
@@ -1027,12 +1027,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dbiculocale == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
{
if (dlocale && dlocale->arg)
- dbiculocale = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
else
- dbiculocale = src_iculocale;
+ dblocale = src_locale;
}
if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
dbicurules = src_icurules;
@@ -1071,7 +1071,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* This would happen if template0 uses the libc provider but the new
* database uses icu.
*/
- if (!dbiculocale)
+ if (!dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALE or ICU_LOCALE must be specified")));
@@ -1081,26 +1081,26 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* database, preserve locale string. Otherwise, canonicalize to a
* language tag.
*/
- if (!IsBinaryUpgrade && dbiculocale != src_iculocale)
+ if (!IsBinaryUpgrade && dblocale != src_locale)
{
- char *langtag = icu_language_tag(dbiculocale,
+ char *langtag = icu_language_tag(dblocale,
icu_validation_level);
- if (langtag && strcmp(dbiculocale, langtag) != 0)
+ if (langtag && strcmp(dblocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, dbiculocale)));
+ langtag, dblocale)));
- dbiculocale = langtag;
+ dblocale = langtag;
}
}
- icu_validate_locale(dbiculocale);
+ icu_validate_locale(dblocale);
}
else
{
- if (dbiculocale)
+ if (dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1157,13 +1157,13 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
char *val1;
char *val2;
- Assert(dbiculocale);
- Assert(src_iculocale);
- if (strcmp(dbiculocale, src_iculocale) != 0)
+ Assert(dblocale);
+ Assert(src_locale);
+ if (strcmp(dblocale, src_locale) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("new ICU locale (%s) is incompatible with the ICU locale of the template database (%s)",
- dbiculocale, src_iculocale),
+ dblocale, src_locale),
errhint("Use the same ICU locale as in the template database, or use template0 as template.")));
val1 = dbicurules;
@@ -1197,7 +1197,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *actual_versionstr;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1225,7 +1225,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1364,8 +1364,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dbiculocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dbiculocale));
+ Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
+ (dblocprovider != COLLPROVIDER_ICU && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -1383,10 +1383,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);
new_record[Anum_pg_database_datcollate - 1] = CStringGetTextDatum(dbcollate);
new_record[Anum_pg_database_datctype - 1] = CStringGetTextDatum(dbctype);
- if (dbiculocale)
- new_record[Anum_pg_database_daticulocale - 1] = CStringGetTextDatum(dbiculocale);
+ if (dblocale)
+ new_record[Anum_pg_database_datlocale - 1] = CStringGetTextDatum(dblocale);
else
- new_record_nulls[Anum_pg_database_daticulocale - 1] = true;
+ new_record_nulls[Anum_pg_database_datlocale - 1] = true;
if (dbicurules)
new_record[Anum_pg_database_daticurules - 1] = CStringGetTextDatum(dbicurules);
else
@@ -2472,7 +2472,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
if (isnull)
elog(ERROR, "unexpected null in pg_database");
newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
@@ -2670,7 +2670,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
ReleaseSysCache(tp);
@@ -2697,7 +2697,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion)
@@ -2808,13 +2808,13 @@ get_db_info(const char *name, LOCKMODE lockmode,
datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datctype);
*dbCtype = TextDatumGetCString(datum);
}
- if (dbIculocale)
+ if (dbLocale)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_daticulocale, &isnull);
+ datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datlocale, &isnull);
if (isnull)
- *dbIculocale = NULL;
+ *dbLocale = NULL;
else
- *dbIculocale = TextDatumGetCString(datum);
+ *dbLocale = TextDatumGetCString(datum);
}
if (dbIcurules)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 79b59b0af7..45fe847320 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1606,7 +1606,7 @@ pg_newlocale_from_collation(Oid collid)
const char *iculocstr;
const char *icurules;
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colliculocale);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
iculocstr = TextDatumGetCString(datum);
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
@@ -1627,7 +1627,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
TextDatumGetCString(datum));
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5ffe9bdd98..154912ecb4 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -320,7 +320,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
bool isnull;
char *collate;
char *ctype;
- char *iculocale;
+ char *datlocale;
/* Fetch our pg_database row normally, via syscache */
tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
@@ -429,8 +429,8 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *icurules;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_daticulocale);
- iculocale = TextDatumGetCString(datum);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
if (!isnull)
@@ -438,10 +438,10 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
else
icurules = NULL;
- make_icu_collator(iculocale, icurules, &default_locale);
+ make_icu_collator(datlocale, icurules, &default_locale);
}
else
- iculocale = NULL;
+ datlocale = NULL;
default_locale.provider = dbform->datlocprovider;
@@ -466,7 +466,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? iculocale : collate);
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ac409b0006..90f793632a 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -145,7 +145,7 @@ static char *lc_numeric = NULL;
static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
-static char *icu_locale = NULL;
+static char *datlocale = NULL;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -1515,8 +1515,8 @@ bootstrap_template1(void)
bki_lines = replace_token(bki_lines, "LC_CTYPE",
escape_quotes_bki(lc_ctype));
- bki_lines = replace_token(bki_lines, "ICU_LOCALE",
- icu_locale ? escape_quotes_bki(icu_locale) : "_null_");
+ bki_lines = replace_token(bki_lines, "DATLOCALE",
+ datlocale ? escape_quotes_bki(datlocale) : "_null_");
bki_lines = replace_token(bki_lines, "ICU_RULES",
icu_rules ? escape_quotes_bki(icu_rules) : "_null_");
@@ -2363,8 +2363,8 @@ setlocales(void)
lc_monetary = locale;
if (!lc_messages)
lc_messages = locale;
- if (!icu_locale && locale_provider == COLLPROVIDER_ICU)
- icu_locale = locale;
+ if (!datlocale && locale_provider != COLLPROVIDER_LIBC)
+ datlocale = locale;
}
/*
@@ -2395,17 +2395,17 @@ setlocales(void)
char *langtag;
/* acquire default locale from the environment, if not specified */
- if (icu_locale == NULL)
+ if (datlocale == NULL)
pg_fatal("ICU locale must be specified");
/* canonicalize to a language tag */
- langtag = icu_language_tag(icu_locale);
+ langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
- langtag, icu_locale);
- pg_free(icu_locale);
- icu_locale = langtag;
+ langtag, datlocale);
+ pg_free(datlocale);
+ datlocale = langtag;
- icu_validate_locale(icu_locale);
+ icu_validate_locale(datlocale);
/*
* In supported builds, the ICU locale ID will be opened during
@@ -2599,14 +2599,14 @@ setup_locale_encoding(void)
strcmp(lc_ctype, lc_numeric) == 0 &&
strcmp(lc_ctype, lc_monetary) == 0 &&
strcmp(lc_ctype, lc_messages) == 0 &&
- (!icu_locale || strcmp(lc_ctype, icu_locale) == 0))
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (icu_locale)
- printf(_(" ICU locale: %s\n"), icu_locale);
+ if (datlocale)
+ printf(_(" ICU locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3277,7 +3277,7 @@ main(int argc, char *argv[])
pg_fatal("unrecognized locale provider: %s", optarg);
break;
case 16:
- icu_locale = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
break;
case 17:
icu_rules = pg_strdup(optarg);
@@ -3312,7 +3312,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (icu_locale && locale_provider != COLLPROVIDER_ICU)
+ if (datlocale && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 2225a12718..a67b4b8225 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2984,7 +2984,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider,
i_collate,
i_ctype,
- i_daticulocale,
+ i_datlocale,
i_daticurules,
i_frozenxid,
i_minmxid,
@@ -3003,7 +3003,7 @@ dumpDatabase(Archive *fout)
*datlocprovider,
*collate,
*ctype,
- *iculocale,
+ *locale,
*icurules,
*datistemplate,
*datconnlimit,
@@ -3027,10 +3027,12 @@ dumpDatabase(Archive *fout)
appendPQExpBufferStr(dbQry, "datminmxid, ");
else
appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
- if (fout->remoteVersion >= 150000)
- appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale, datcollversion, ");
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
+ else if (fout->remoteVersion >= 150000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
else
- appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS daticulocale, NULL AS datcollversion, ");
+ appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(dbQry, "daticurules, ");
else
@@ -3051,7 +3053,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider = PQfnumber(res, "datlocprovider");
i_collate = PQfnumber(res, "datcollate");
i_ctype = PQfnumber(res, "datctype");
- i_daticulocale = PQfnumber(res, "daticulocale");
+ i_datlocale = PQfnumber(res, "datlocale");
i_daticurules = PQfnumber(res, "daticurules");
i_frozenxid = PQfnumber(res, "datfrozenxid");
i_minmxid = PQfnumber(res, "datminmxid");
@@ -3070,10 +3072,10 @@ dumpDatabase(Archive *fout)
datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
collate = PQgetvalue(res, 0, i_collate);
ctype = PQgetvalue(res, 0, i_ctype);
- if (!PQgetisnull(res, 0, i_daticulocale))
- iculocale = PQgetvalue(res, 0, i_daticulocale);
+ if (!PQgetisnull(res, 0, i_datlocale))
+ locale = PQgetvalue(res, 0, i_datlocale);
else
- iculocale = NULL;
+ locale = NULL;
if (!PQgetisnull(res, 0, i_daticurules))
icurules = PQgetvalue(res, 0, i_daticurules);
else
@@ -3138,11 +3140,12 @@ dumpDatabase(Archive *fout)
appendStringLiteralAH(creaQry, ctype, fout);
}
}
- if (iculocale)
+ if (locale)
{
appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
- appendStringLiteralAH(creaQry, iculocale, fout);
+ appendStringLiteralAH(creaQry, locale, fout);
}
+
if (icurules)
{
appendPQExpBufferStr(creaQry, " ICU_RULES = ");
@@ -13756,12 +13759,12 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
int i_collisdeterministic;
int i_collcollate;
int i_collctype;
- int i_colliculocale;
+ int i_colllocale;
int i_collicurules;
const char *collprovider;
const char *collcollate;
const char *collctype;
- const char *colliculocale;
+ const char *colllocale;
const char *collicurules;
/* Do nothing in data-only dump */
@@ -13793,12 +13796,15 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
appendPQExpBufferStr(query,
"true AS collisdeterministic, ");
- if (fout->remoteVersion >= 150000)
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(query,
+ "colllocale, ");
+ else if (fout->remoteVersion >= 150000)
appendPQExpBufferStr(query,
- "colliculocale, ");
+ "colliculocale AS colllocale, ");
else
appendPQExpBufferStr(query,
- "NULL AS colliculocale, ");
+ "NULL AS colllocale, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(query,
@@ -13820,7 +13826,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
i_collisdeterministic = PQfnumber(res, "collisdeterministic");
i_collcollate = PQfnumber(res, "collcollate");
i_collctype = PQfnumber(res, "collctype");
- i_colliculocale = PQfnumber(res, "colliculocale");
+ i_colllocale = PQfnumber(res, "colllocale");
i_collicurules = PQfnumber(res, "collicurules");
collprovider = PQgetvalue(res, 0, i_collprovider);
@@ -13847,10 +13853,10 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
collctype = NULL;
}
- if (!PQgetisnull(res, 0, i_colliculocale))
- colliculocale = PQgetvalue(res, 0, i_colliculocale);
+ if (!PQgetisnull(res, 0, i_colllocale))
+ colllocale = PQgetvalue(res, 0, i_colllocale);
else
- colliculocale = NULL;
+ colllocale = NULL;
if (!PQgetisnull(res, 0, i_collicurules))
collicurules = PQgetvalue(res, 0, i_collicurules);
@@ -13880,7 +13886,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
if (collprovider[0] == 'd')
{
- if (collcollate || collctype || colliculocale || collicurules)
+ if (collcollate || collctype || colllocale || collicurules)
pg_log_warning("invalid collation \"%s\"", qcollname);
/* no locale -- the default collation cannot be reloaded anyway */
@@ -13889,16 +13895,16 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
{
if (fout->remoteVersion >= 150000)
{
- if (collcollate || collctype || !colliculocale)
+ if (collcollate || collctype || !colllocale)
pg_log_warning("invalid collation \"%s\"", qcollname);
appendPQExpBufferStr(q, ", locale = ");
- appendStringLiteralAH(q, colliculocale ? colliculocale : "",
+ appendStringLiteralAH(q, colllocale ? colllocale : "",
fout);
}
else
{
- if (!collcollate || !collctype || colliculocale ||
+ if (!collcollate || !collctype || colllocale ||
strcmp(collcollate, collctype) != 0)
pg_log_warning("invalid collation \"%s\"", qcollname);
@@ -13914,7 +13920,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
}
else if (collprovider[0] == 'c')
{
- if (colliculocale || collicurules || !collcollate || !collctype)
+ if (colllocale || collicurules || !collcollate || !collctype)
pg_log_warning("invalid collation \"%s\"", qcollname);
if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c
index 183c2f84eb..101fe855fc 100644
--- a/src/bin/pg_upgrade/info.c
+++ b/src/bin/pg_upgrade/info.c
@@ -328,18 +328,24 @@ get_template0_info(ClusterInfo *cluster)
int i_datlocprovider;
int i_datcollate;
int i_datctype;
- int i_daticulocale;
+ int i_datlocale;
- if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
dbres = executeQueryOrDie(conn,
"SELECT encoding, datlocprovider, "
- " datcollate, datctype, daticulocale "
+ " datcollate, datctype, datlocale "
+ "FROM pg_catalog.pg_database "
+ "WHERE datname='template0'");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ dbres = executeQueryOrDie(conn,
+ "SELECT encoding, datlocprovider, "
+ " datcollate, datctype, daticulocale AS datlocale"
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
else
dbres = executeQueryOrDie(conn,
"SELECT encoding, 'c' AS datlocprovider, "
- " datcollate, datctype, NULL AS daticulocale "
+ " datcollate, datctype, NULL AS datlocale "
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
@@ -353,16 +359,16 @@ get_template0_info(ClusterInfo *cluster)
i_datlocprovider = PQfnumber(dbres, "datlocprovider");
i_datcollate = PQfnumber(dbres, "datcollate");
i_datctype = PQfnumber(dbres, "datctype");
- i_daticulocale = PQfnumber(dbres, "daticulocale");
+ i_datlocale = PQfnumber(dbres, "datlocale");
locale->db_encoding = atoi(PQgetvalue(dbres, 0, i_datencoding));
locale->db_collprovider = PQgetvalue(dbres, 0, i_datlocprovider)[0];
locale->db_collate = pg_strdup(PQgetvalue(dbres, 0, i_datcollate));
locale->db_ctype = pg_strdup(PQgetvalue(dbres, 0, i_datctype));
- if (PQgetisnull(dbres, 0, i_daticulocale))
- locale->db_iculocale = NULL;
+ if (PQgetisnull(dbres, 0, i_datlocale))
+ locale->db_locale = NULL;
else
- locale->db_iculocale = pg_strdup(PQgetvalue(dbres, 0, i_daticulocale));
+ locale->db_locale = pg_strdup(PQgetvalue(dbres, 0, i_datlocale));
cluster->template0 = locale;
@@ -392,12 +398,15 @@ get_db_infos(ClusterInfo *cluster)
snprintf(query, sizeof(query),
"SELECT d.oid, d.datname, d.encoding, d.datcollate, d.datctype, ");
- if (GET_MAJOR_VERSION(cluster->major_version) < 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
+ snprintf(query + strlen(query), sizeof(query) - strlen(query),
+ "datlocprovider, datlocale, ");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "'c' AS datlocprovider, NULL AS daticulocale, ");
+ "datlocprovider, daticulocale AS datlocale, ");
else
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "datlocprovider, daticulocale, ");
+ "'c' AS datlocprovider, NULL AS datlocale, ");
snprintf(query + strlen(query), sizeof(query) - strlen(query),
"pg_catalog.pg_tablespace_location(t.oid) AS spclocation "
"FROM pg_catalog.pg_database d "
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 10c94a6c1f..bb261353bd 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -391,7 +391,7 @@ setup(char *argv0, bool *live_check)
* Copy locale and encoding information into the new cluster's template0.
*
* We need to copy the encoding, datlocprovider, datcollate, datctype, and
- * daticulocale. We don't need datcollversion because that's never set for
+ * datlocale. We don't need datcollversion because that's never set for
* template0.
*/
static void
@@ -400,7 +400,7 @@ set_locale_and_encoding(void)
PGconn *conn_new_template1;
char *datcollate_literal;
char *datctype_literal;
- char *daticulocale_literal = NULL;
+ char *datlocale_literal = NULL;
DbLocaleInfo *locale = old_cluster.template0;
prep_status("Setting locale and encoding for new cluster");
@@ -414,15 +414,29 @@ set_locale_and_encoding(void)
datctype_literal = PQescapeLiteral(conn_new_template1,
locale->db_ctype,
strlen(locale->db_ctype));
- if (locale->db_iculocale)
- daticulocale_literal = PQescapeLiteral(conn_new_template1,
- locale->db_iculocale,
- strlen(locale->db_iculocale));
+ if (locale->db_locale)
+ datlocale_literal = PQescapeLiteral(conn_new_template1,
+ locale->db_locale,
+ strlen(locale->db_locale));
else
- daticulocale_literal = pg_strdup("NULL");
+ datlocale_literal = pg_strdup("NULL");
/* update template0 in new cluster */
- if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
+ if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1700)
+ PQclear(executeQueryOrDie(conn_new_template1,
+ "UPDATE pg_catalog.pg_database "
+ " SET encoding = %d, "
+ " datlocprovider = '%c', "
+ " datcollate = %s, "
+ " datctype = %s, "
+ " datlocale = %s "
+ " WHERE datname = 'template0' ",
+ locale->db_encoding,
+ locale->db_collprovider,
+ datcollate_literal,
+ datctype_literal,
+ datlocale_literal));
+ else if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
" SET encoding = %d, "
@@ -435,7 +449,7 @@ set_locale_and_encoding(void)
locale->db_collprovider,
datcollate_literal,
datctype_literal,
- daticulocale_literal));
+ datlocale_literal));
else
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
@@ -449,7 +463,7 @@ set_locale_and_encoding(void)
PQfreemem(datcollate_literal);
PQfreemem(datctype_literal);
- PQfreemem(daticulocale_literal);
+ PQfreemem(datlocale_literal);
PQfinish(conn_new_template1);
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index d9a848cbfd..70ac424bc9 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -208,7 +208,7 @@ typedef struct
char *db_collate;
char *db_ctype;
char db_collprovider;
- char *db_iculocale;
+ char *db_locale;
int db_encoding;
} DbLocaleInfo;
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index d951ed3af0..41d06d272b 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -104,6 +104,8 @@ if ($oldnode->pg_version >= 11)
push @custom_opts, '--allow-group-access';
}
+my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
+
# Set up the locale settings for the original cluster, so that we
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
@@ -111,15 +113,22 @@ if ($oldnode->pg_version >= 11)
my $original_encoding = "6"; # UTF-8
my $original_provider = "c";
my $original_locale = "C";
-my $original_iculocale = "";
+my $original_datlocale = "";
my $provider_field = "'c' AS datlocprovider";
-my $iculocale_field = "NULL AS daticulocale";
-if ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
+my $datlocale_field = "NULL AS datlocale";
+if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$provider_field = "datlocprovider";
- $iculocale_field = "daticulocale";
+ if ($oldversion >= 17)
+ {
+ $datlocale_field = "datlocale";
+ }
+ else
+ {
+ $datlocale_field = "daticulocale AS datlocale";
+ }
$original_provider = "i";
- $original_iculocale = "fr-CA";
+ $original_datlocale = "fr-CA";
}
my @initdb_params = @custom_opts;
@@ -139,10 +148,10 @@ $oldnode->start;
my $result;
$result = $oldnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -422,10 +431,10 @@ if (-d $log_path)
# Test that upgraded cluster has original locale settings.
$result = $newnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index b6a4eb1d56..b943569050 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -937,14 +937,18 @@ listAllDbs(const char *pattern, bool verbose)
" d.datctype as \"%s\",\n",
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " d.datlocale as \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" d.daticulocale as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" NULL as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
" d.daticurules as \"%s\",\n",
@@ -4983,14 +4987,18 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " c.colllocale AS \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" c.colliculocale AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" c.collcollate AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 10c363d2ee..7396ff10c4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -29,6 +29,6 @@
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
- colliculocale => 'und' },
+ colllocale => 'und' },
]
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 5f08eb0a4a..a3e196fb53 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -42,7 +42,7 @@ CATALOG(pg_collation,3456,CollationRelationId)
#ifdef CATALOG_VARLEN /* variable-length fields start here */
text collcollate BKI_DEFAULT(_null_); /* LC_COLLATE setting */
text collctype BKI_DEFAULT(_null_); /* LC_CTYPE setting */
- text colliculocale BKI_DEFAULT(_null_); /* ICU locale ID */
+ text colllocale BKI_DEFAULT(_null_); /* locale ID */
text collicurules BKI_DEFAULT(_null_); /* ICU collation rules */
text collversion BKI_DEFAULT(_null_); /* provider-dependent
* version of collation
@@ -94,7 +94,7 @@ extern Oid CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
diff --git a/src/include/catalog/pg_database.dat b/src/include/catalog/pg_database.dat
index 4306e8a3e8..c2ba636f8d 100644
--- a/src/include/catalog/pg_database.dat
+++ b/src/include/catalog/pg_database.dat
@@ -18,7 +18,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE',
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE',
daticurules => 'ICU_RULES', datacl => '_null_' },
]
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 014baa7bab..dbd4379ffa 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -75,7 +75,7 @@ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID
text datctype BKI_FORCE_NOT_NULL;
/* ICU locale ID */
- text daticulocale;
+ text datlocale;
/* ICU collation rules */
text daticurules;
diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out
index 7a05c75967..8ca93f4dea 100644
--- a/src/test/regress/expected/collate.icu.utf8.out
+++ b/src/test/regress/expected/collate.icu.utf8.out
@@ -1024,7 +1024,7 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
@@ -1032,7 +1032,7 @@ ERROR: collation "test0" already exists
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
RESET icu_validation_level;
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index ad02772562..69060fe3c0 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -6221,9 +6221,9 @@ List of schemas
(0 rows)
\dO "no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.access.privilege"
@@ -6410,9 +6410,9 @@ cross-database references are not implemented: "no.such.schema"."no.such.languag
(0 rows)
\dO "no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.schema"."no.such.access.privilege"
@@ -6553,9 +6553,9 @@ List of text search templates
(0 rows)
\dO regression."no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp regression."no.such.schema"."no.such.access.privilege"
diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql
index 3db9e25913..03837de846 100644
--- a/src/test/regress/sql/collate.icu.utf8.sql
+++ b/src/test/regress/sql/collate.icu.utf8.sql
@@ -363,14 +363,14 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
--
2.34.1
[text/x-patch] v19-0005-Introduce-collation-provider-builtin.patch (86.5K, ../../[email protected]/6-v19-0005-Introduce-collation-provider-builtin.patch)
download | inline diff:
From 3b580005bcef19c5ee567698f7742981622f63f5 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 1 May 2023 15:38:29 -0700
Subject: [PATCH v19 5/6] Introduce collation provider "builtin".
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Three locales are offered by the builtin provider: C, C.UTF-8, and
PG_UNICODE_FAST.
The builtin "C" locale is equal in semantics and implementation to
the libc "C" locale (neither of which actually use libc).
The builtin "C.UTF-8" locale offers similar semantics to the libc
"C.UTF-8" locale, which is collation according to code point combined
with simple Unicode character semantics. Unlike the libc "C.UTF-8"
locale, the builtin "C.UTF-8" is available on all platforms with
consistent behavior, and benefits from additional optimizations.
The builtin "PG_UNICODE_FAST" locale offers collation according to
code point order and more complete Unicode character semantics. As the
SQL standard requires, it offers full case mappings that may increase
the length of a string, such as "ß" changing to "SS" when uppercased.
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 88 ++++--
doc/src/sgml/ref/create_collation.sgml | 11 +-
doc/src/sgml/ref/create_database.sgml | 8 +-
doc/src/sgml/ref/createdb.sgml | 2 +-
doc/src/sgml/ref/initdb.sgml | 17 +-
src/backend/catalog/pg_collation.c | 5 +-
src/backend/commands/collationcmds.c | 93 ++++--
src/backend/commands/dbcommands.c | 121 ++++++--
src/backend/regex/regc_pg_locale.c | 41 ++-
src/backend/utils/adt/formatting.c | 147 ++++++++++
src/backend/utils/adt/pg_locale.c | 162 +++++++++--
src/backend/utils/init/postinit.c | 46 ++-
src/bin/initdb/initdb.c | 58 ++--
src/bin/initdb/t/001_initdb.pl | 57 +++-
src/bin/pg_dump/pg_dump.c | 49 ++--
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 70 +++--
src/bin/psql/describe.c | 4 +-
src/bin/scripts/createdb.c | 18 +-
src/bin/scripts/t/020_createdb.pl | 78 +++++
src/include/catalog/pg_collation.dat | 6 +-
src/include/catalog/pg_collation.h | 3 +
src/include/utils/pg_locale.h | 9 +-
src/test/icu/t/010_database.pl | 22 +-
src/test/regress/expected/collate.out | 24 +-
src/test/regress/expected/collate.utf8.out | 288 +++++++++++++++++++
src/test/regress/expected/collate.utf8_1.out | 8 +
src/test/regress/parallel_schedule | 4 +-
src/test/regress/sql/collate.sql | 10 +
src/test/regress/sql/collate.utf8.sql | 123 ++++++++
29 files changed, 1409 insertions(+), 163 deletions(-)
create mode 100644 src/test/regress/expected/collate.utf8.out
create mode 100644 src/test/regress/expected/collate.utf8_1.out
create mode 100644 src/test/regress/sql/collate.utf8.sql
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 4422b0cc92..2abd898115 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -342,22 +342,14 @@ initdb --locale=sv_SE
<title>Locale Providers</title>
<para>
- <productname>PostgreSQL</productname> supports multiple <firstterm>locale
- providers</firstterm>. This specifies which library supplies the locale
- data. One standard provider name is <literal>libc</literal>, which uses
- the locales provided by the operating system C library. These are the
- locales used by most tools provided by the operating system. Another
- provider is <literal>icu</literal>, which uses the external
- ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can
- only be used if support for ICU was configured when PostgreSQL was built.
+ A locale provider specifies which library defines the locale behavior for
+ collations and character classifications.
</para>
<para>
The commands and tools that select the locale settings, as described
- above, each have an option to select the locale provider. The examples
- shown earlier all use the <literal>libc</literal> provider, which is the
- default. Here is an example to initialize a database cluster using the
- ICU provider:
+ above, each have an option to select the locale provider. Here is an
+ example to initialize a database cluster using the ICU provider:
<programlisting>
initdb --locale-provider=icu --icu-locale=en
</programlisting>
@@ -370,12 +362,74 @@ initdb --locale-provider=icu --icu-locale=en
</para>
<para>
- Which locale provider to use depends on individual requirements. For most
- basic uses, either provider will give adequate results. For the libc
- provider, it depends on what the operating system offers; some operating
- systems are better than others. For advanced uses, ICU offers more locale
- variants and customization options.
+ Regardless of the locale provider, the operating system is still used to
+ provide some locale-aware behavior, such as messages (see <xref
+ linkend="guc-lc-messages"/>).
</para>
+
+ <para>
+ The available locale providers are listed below.
+ </para>
+
+ <sect3 id="locale-provider-builtin">
+ <title>Builtin</title>
+ <para>
+ The <literal>builtin</literal> provider uses built-in operations. Only
+ the <literal>C</literal> and <literal>C.UTF-8</literal> locales are
+ supported for this provider.
+ </para>
+ <para>
+ The <literal>C</literal> locale behavior is identical to the
+ <literal>C</literal> locale in the libc provider. When using this locale,
+ the behavior may depend on the database encoding.
+ </para>
+ <para>
+ The <literal>C.UTF-8</literal> locale is available only for when the
+ database encoding is <literal>UTF-8</literal>, and the behavior is based
+ on Unicode. The collation uses the code point values only. The regular
+ expression character classes are based on the "POSIX Compatible"
+ semantics, and the case mapping is the "simple" variant.
+ </para>
+ </sect3>
+ <sect3 id="locale-provider-icu">
+ <title>ICU</title>
+ <para>
+ The <literal>icu</literal> provider uses the external
+ ICU<indexterm><primary>ICU</primary></indexterm>
+ library. <productname>PostgreSQL</productname> must have been configured
+ with support.
+ </para>
+ <para>
+ ICU provides collation and character classification behavior that is
+ independent of the operating system and database encoding, which is
+ preferable if you expect to transition to other platforms without any
+ change in results. <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal> can be set independently of the ICU locale.
+ </para>
+ <note>
+ <para>
+ For the ICU provider, results may depend on the version of the ICU
+ library used, as it is updated to reflect changes in natural language
+ over time.
+ </para>
+ </note>
+ </sect3>
+ <sect3 id="locale-provider-libc">
+ <title>libc</title>
+ <para>
+ The <literal>libc</literal> provider uses the operating system's C
+ library. The collation and character classification behavior is
+ controlled by the settings <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal>, so they cannot be set independently.
+ </para>
+ <note>
+ <para>
+ The same locale name may have different behavior on different platforms
+ when using the libc provider.
+ </para>
+ </note>
+ </sect3>
+
</sect2>
<sect2 id="icu-locales">
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 5cf9777764..85f18cbbe5 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -96,6 +96,11 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<replaceable>locale</replaceable>, you cannot specify either of those
parameters.
</para>
+ <para>
+ If <replaceable>provider</replaceable> is <literal>builtin</literal>,
+ then <replaceable>locale</replaceable> must be specified and set to
+ either <literal>C</literal> or <literal>C.UTF-8</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -129,9 +134,9 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<listitem>
<para>
Specifies the provider to use for locale services associated with this
- collation. Possible values are
- <literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
- (if the server was built with ICU support) or <literal>libc</literal>.
+ collation. Possible values are <literal>builtin</literal>,
+ <literal>icu</literal><indexterm><primary>ICU</primary></indexterm> (if
+ the server was built with ICU support) or <literal>libc</literal>.
<literal>libc</literal> is the default. See <xref
linkend="locale-providers"/> for details.
</para>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 72927960eb..1f5cdf1271 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -162,6 +162,12 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
linkend="create-database-lc-ctype"/>, or <xref
linkend="create-database-icu-locale"/> individually.
</para>
+ <para>
+ If <xref linkend="create-database-locale-provider"/> is
+ <literal>builtin</literal>, then <replaceable>locale</replaceable>
+ must be specified and set to either <literal>C</literal> or
+ <literal>C.UTF-8</literal>.
+ </para>
<tip>
<para>
The other locale settings <xref linkend="guc-lc-messages"/>, <xref
@@ -243,7 +249,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<listitem>
<para>
Specifies the provider to use for the default collation in this
- database. Possible values are
+ database. Possible values are <literal>builtin</literal>,
<literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
(if the server was built with ICU support) or <literal>libc</literal>.
By default, the provider is the same as that of the <xref
diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml
index e4647d5ce7..d3e815f659 100644
--- a/doc/src/sgml/ref/createdb.sgml
+++ b/doc/src/sgml/ref/createdb.sgml
@@ -171,7 +171,7 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
Specifies the locale provider for the database's default collation.
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index cd75cae10e..08a1c2538f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -286,6 +286,11 @@ PostgreSQL documentation
environment that <command>initdb</command> runs in. Locale
support is described in <xref linkend="locale"/>.
</para>
+ <para>
+ If <option>--locale-provider</option> is <literal>builtin</literal>,
+ <option>--locale</option> must be specified and set to
+ <literal>C</literal> or <literal>C.UTF-8</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -314,8 +319,18 @@ PostgreSQL documentation
</listitem>
</varlistentry>
+ <varlistentry id="app-initdb-builtin-locale">
+ <term><option>--builtin-locale=<replaceable>locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the locale name when the builtin provider is used. Locale support
+ is described in <xref linkend="locale"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-initdb-option-locale-provider">
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
This option sets the locale provider for databases created in the new
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 7bad94f908..01e91000af 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -68,7 +68,10 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colllocale);
+ Assert((collprovider == COLLPROVIDER_LIBC &&
+ collcollate && collctype && !colllocale) ||
+ (collprovider != COLLPROVIDER_LIBC &&
+ !collcollate && !collctype && colllocale));
/*
* Make sure there is no existing collation of same name & encoding.
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 27564e569a..0fa073496e 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -68,7 +68,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colllocale;
+ const char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -215,7 +215,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (collproviderstr)
{
- if (pg_strcasecmp(collproviderstr, "icu") == 0)
+ if (pg_strcasecmp(collproviderstr, "builtin") == 0)
+ collprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(collproviderstr, "icu") == 0)
collprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(collproviderstr, "libc") == 0)
collprovider = COLLPROVIDER_LIBC;
@@ -245,7 +247,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (lcctypeEl)
collctype = defGetString(lcctypeEl);
- if (collprovider == COLLPROVIDER_LIBC)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ if (!colllocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("parameter \"locale\" must be specified")));
+
+ colllocale = builtin_validate_locale(GetDatabaseEncoding(),
+ colllocale);
+ }
+ else if (collprovider == COLLPROVIDER_LIBC)
{
if (!collcollate)
ereport(ERROR,
@@ -305,7 +317,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
- if (collprovider == COLLPROVIDER_ICU)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * Behavior may be different in different encodings, so set
+ * collencoding to the current database encoding. No validation is
+ * required, because the "builtin" provider is compatible with any
+ * encoding.
+ */
+ collencoding = GetDatabaseEncoding();
+ }
+ else if (collprovider == COLLPROVIDER_ICU)
{
#ifdef USE_ICU
/*
@@ -334,7 +356,18 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
+ {
+ const char *locale;
+
+ if (collprovider == COLLPROVIDER_ICU)
+ locale = colllocale;
+ else if (collprovider == COLLPROVIDER_LIBC)
+ locale = collcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ collversion = get_collation_actual_version(collprovider, locale);
+ }
newoid = CollationCreate(collName,
collNamespace,
@@ -409,6 +442,7 @@ AlterCollation(AlterCollationStmt *stmt)
Form_pg_collation collForm;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
ObjectAddress address;
@@ -435,8 +469,20 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
+ if (collForm->collprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (collForm->collprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(collForm->collprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -500,11 +546,18 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_datlocale : Anum_pg_database_datcollate);
-
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(dbtup);
}
@@ -521,11 +574,19 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttrNotNull(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(colltp);
}
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index d1de46e759..d7a21adc5c 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -698,6 +698,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
DefElem *dtemplate = NULL;
DefElem *dencoding = NULL;
DefElem *dlocale = NULL;
+ DefElem *dbuiltinlocale = NULL;
DefElem *dcollate = NULL;
DefElem *dctype = NULL;
DefElem *diculocale = NULL;
@@ -713,7 +714,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dblocale = NULL;
+ const char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -762,6 +763,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errorConflictingDefElem(defel, pstate);
dlocale = defel;
}
+ else if (strcmp(defel->defname, "builtin_locale") == 0)
+ {
+ if (dbuiltinlocale)
+ errorConflictingDefElem(defel, pstate);
+ dbuiltinlocale = defel;
+ }
else if (strcmp(defel->defname, "lc_collate") == 0)
{
if (dcollate)
@@ -897,7 +904,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
dbcollate = defGetString(dlocale);
dbctype = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
}
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ dblocale = defGetString(dbuiltinlocale);
if (dcollate && dcollate->arg)
dbcollate = defGetString(dcollate);
if (dctype && dctype->arg)
@@ -910,7 +920,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *locproviderstr = defGetString(dlocprovider);
- if (pg_strcasecmp(locproviderstr, "icu") == 0)
+ if (pg_strcasecmp(locproviderstr, "builtin") == 0)
+ dblocprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(locproviderstr, "icu") == 0)
dblocprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(locproviderstr, "libc") == 0)
dblocprovider = COLLPROVIDER_LIBC;
@@ -1027,14 +1039,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
- {
- if (dlocale && dlocale->arg)
- dblocale = defGetString(dlocale);
- else
- dblocale = src_locale;
- }
- if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL)
+ dblocale = src_locale;
+ if (dbicurules == NULL)
dbicurules = src_icurules;
/* Some encodings are client only */
@@ -1059,6 +1066,27 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
check_encoding_locale_matches(encoding, dbcollate, dbctype);
+ if (dblocprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * This would happen if template0 uses the libc provider but the new
+ * database uses builtin.
+ */
+ if (!dblocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("LOCALE must be specified for the builtin provider")));
+
+ dblocale = builtin_validate_locale(encoding, dblocale);
+ }
+ else
+ {
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("BUILTIN_LOCALE cannot be specified unless locale provider is builtin")));
+ }
+
if (dblocprovider == COLLPROVIDER_ICU)
{
if (!(is_encoding_supported_by_icu(encoding)))
@@ -1100,7 +1128,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
}
else
{
- if (dblocale)
+ if (diculocale && diculocale->arg)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1111,6 +1139,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
}
+ /* for libc, locale comes from datcollate and datctype */
+ if (dblocprovider == COLLPROVIDER_LIBC)
+ dblocale = NULL;
+
/*
* Check that the new encoding and locale settings match the source
* database. We insist on this because we simply copy the source data ---
@@ -1196,8 +1228,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (src_collversion && !dcollversion)
{
char *actual_versionstr;
+ const char *locale;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ actual_versionstr = get_collation_actual_version(dblocprovider, locale);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1225,7 +1265,18 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ {
+ const char *locale;
+
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ dbcollversion = get_collation_actual_version(dblocprovider, locale);
+ }
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1364,8 +1415,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dblocale));
+ Assert((dblocprovider != COLLPROVIDER_LIBC && dblocale) ||
+ (dblocprovider == COLLPROVIDER_LIBC && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -2446,6 +2497,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
ObjectAddress address;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
@@ -2472,10 +2524,24 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
- newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
+ if (datForm->datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datlocale, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datForm->datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(datForm->datlocprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -2660,6 +2726,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
+ char *locale;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2670,8 +2737,20 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
- version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
+ if (datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ version = get_collation_actual_version(datlocprovider, locale);
ReleaseSysCache(tp);
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 6a26388bfa..d612731319 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -16,6 +16,8 @@
*/
#include "catalog/pg_collation.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "utils/pg_locale.h"
/*
@@ -64,6 +66,7 @@
typedef enum
{
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
+ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
@@ -75,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -266,7 +271,15 @@ pg_set_regex_collation(Oid collation)
if (GetDatabaseEncoding() == PG_UTF8)
{
if (pg_regex_locale)
- pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ {
+ if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
+ pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = pg_regex_locale->info.builtin.properties_posix;
+ }
+ else
+ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
@@ -290,6 +303,8 @@ pg_wc_isdigit(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -322,6 +337,8 @@ pg_wc_isalpha(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALPHA));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
@@ -354,6 +371,8 @@ pg_wc_isalnum(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -395,6 +414,8 @@ pg_wc_isupper(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISUPPER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
@@ -427,6 +448,8 @@ pg_wc_islower(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISLOWER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
@@ -459,6 +482,8 @@ pg_wc_isgraph(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISGRAPH));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
@@ -491,6 +516,8 @@ pg_wc_isprint(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPRINT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
@@ -523,6 +550,8 @@ pg_wc_ispunct(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
@@ -555,6 +584,8 @@ pg_wc_isspace(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISSPACE));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
@@ -588,6 +619,8 @@ pg_wc_toupper(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_uppercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -628,6 +661,8 @@ pg_wc_tolower(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_lowercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -792,6 +827,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
#endif
break;
+ case PG_REGEX_BUILTIN:
+ max_chr = (pg_wchar) MAX_SIMPLE_CHR;
+ break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
@@ -809,6 +847,7 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break;
default:
+ Assert(false);
max_chr = 0; /* can't get here, but keep compiler quiet */
break;
}
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 829aaa8d0e..b9c3ee0125 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -77,6 +77,8 @@
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "mb/pg_wchar.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
@@ -1680,6 +1682,35 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
@@ -1798,6 +1829,35 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
@@ -1861,6 +1921,48 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
return result;
}
+struct WordBoundaryState
+{
+ const char *str;
+ size_t len;
+ size_t offset;
+ bool init;
+ bool prev_alnum;
+ bool posix;
+};
+
+/*
+ * Simple word boundary iterator that draws boundaries each time the result of
+ * pg_u_isalnum() changes.
+ */
+static size_t
+initcap_wbnext(void *state)
+{
+ struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
+
+ while (wbstate->offset < wbstate->len &&
+ wbstate->str[wbstate->offset] != '\0')
+ {
+ pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ wbstate->offset);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
+
+ if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
+ {
+ size_t prev_offset = wbstate->offset;
+
+ wbstate->init = true;
+ wbstate->offset += unicode_utf8len(u);
+ wbstate->prev_alnum = curr_alnum;
+ return prev_offset;
+ }
+
+ wbstate->offset += unicode_utf8len(u);
+ }
+
+ return wbstate->len;
+}
+
/*
* collation-aware, wide-character-aware initcap function
*
@@ -1917,6 +2019,51 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+ struct WordBoundaryState wbstate = {
+ .str = src,
+ .len = srclen,
+ .offset = 0,
+ .init = false,
+ .prev_alnum = false,
+ .posix = mylocale->info.builtin.properties_posix,
+ };
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.titlecase,
+ mylocale->info.builtin.casemap_full,
+ initcap_wbnext, &wbstate);
+ if (needed + 1 > dstsize)
+ {
+ /* reset iterator */
+ wbstate.offset = 0;
+ wbstate.prev_alnum = false;
+
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.titlecase,
+ mylocale->info.builtin.casemap_full,
+ initcap_wbnext, &wbstate);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 45fe847320..dff28d3bf4 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1269,7 +1269,19 @@ lookup_collation_cache(Oid collation, bool set_flags)
elog(ERROR, "cache lookup failed for collation %u", collation);
collform = (Form_pg_collation) GETSTRUCT(tp);
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ Datum datum;
+ const char *colllocale;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ colllocale = TextDatumGetCString(datum);
+
+ cache_entry->collate_is_c = true;
+ cache_entry->ctype_is_c = ((strcmp(colllocale, "C") == 0) ||
+ (strcmp(colllocale, "POSIX") == 0));
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
const char *collcollate;
@@ -1320,16 +1332,30 @@ lc_collate_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_COLLATE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_COLLATE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ result = true;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1373,16 +1399,29 @@ lc_ctype_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_CTYPE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_CTYPE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ localeptr = default_locale.info.builtin.locale;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1390,6 +1429,7 @@ lc_ctype_is_c(Oid collation)
result = true;
else
result = false;
+
return (bool) result;
}
@@ -1520,10 +1560,10 @@ pg_newlocale_from_collation(Oid collid)
if (collid == DEFAULT_COLLATION_OID)
{
- if (default_locale.provider == COLLPROVIDER_ICU)
- return &default_locale;
- else
+ if (default_locale.provider == COLLPROVIDER_LIBC)
return (pg_locale_t) 0;
+ else
+ return &default_locale;
}
cache_entry = lookup_collation_cache(collid, false);
@@ -1548,7 +1588,45 @@ pg_newlocale_from_collation(Oid collid)
result.provider = collform->collprovider;
result.deterministic = collform->collisdeterministic;
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ bool casemap_full;
+ bool titlecase;
+ bool properties_posix;
+
+ const char *locstr;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ locstr = TextDatumGetCString(datum);
+
+ if (strcmp(locstr, "PG_UNICODE_FAST") == 0)
+ {
+ casemap_full = true;
+ titlecase = true;
+ properties_posix = false;
+ }
+ else if (strcmp(locstr, "C.UTF-8") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else if (strcmp(locstr, "C") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else
+ elog(ERROR, "unexpected builtin locale: %s", locstr);
+
+ result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
+ locstr);
+ result.info.builtin.casemap_full = casemap_full;
+ result.info.builtin.titlecase = titlecase;
+ result.info.builtin.properties_posix = properties_posix;
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
const char *collcollate;
const char *collctype pg_attribute_unused();
@@ -1627,6 +1705,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
+ Assert(collform->collprovider != COLLPROVIDER_BUILTIN);
datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
@@ -1678,6 +1757,14 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
+ /*
+ * The only two supported locales (C and C.UTF-8) are both based on memcmp
+ * and do not change. (The ctype behavior can change, but the versioning
+ * does not track that.)
+ */
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ return NULL;
+
#ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU)
{
@@ -2444,6 +2531,43 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
return result;
}
+const char *
+builtin_validate_locale(int encoding, const char *locale)
+{
+ const char *canonical_name = NULL;
+ int required_encoding = -1;
+
+ if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0)
+ {
+ canonical_name = "C";
+ }
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "PG_UNICODE_FAST";
+ }
+ else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "C.UTF-8";
+ }
+
+ if (!canonical_name)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ locale)));
+
+ if (required_encoding >= 0 && encoding != required_encoding)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("encoding \"%s\" does not match locale \"%s\"",
+ pg_encoding_to_char(encoding), locale)));
+
+ return canonical_name;
+}
+
+
#ifdef USE_ICU
/*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 154912ecb4..ef1e5533ec 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -425,7 +425,43 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
strcmp(ctype, "POSIX") == 0)
database_ctype_is_c = true;
- if (dbform->datlocprovider == COLLPROVIDER_ICU)
+ if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
+ {
+ bool casemap_full;
+ bool titlecase;
+ bool properties_posix;
+
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
+
+ if (strcmp(datlocale, "PG_UNICODE_FAST") == 0)
+ {
+ casemap_full = true;
+ titlecase = true;
+ properties_posix = false;
+ }
+ else if (strcmp(datlocale, "C.UTF-8") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else if (strcmp(datlocale, "C") == 0)
+ {
+ casemap_full = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else
+ elog(ERROR, "unexpected builtin locale: %s", datlocale);
+
+ default_locale.info.builtin.locale = MemoryContextStrdup(
+ TopMemoryContext, datlocale);
+ default_locale.info.builtin.casemap_full = casemap_full;
+ default_locale.info.builtin.titlecase = titlecase;
+ default_locale.info.builtin.properties_posix = properties_posix;
+ }
+ else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
char *icurules;
@@ -463,10 +499,16 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *actual_versionstr;
char *collversionstr;
+ char *locale;
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
+ if (dbform->datlocprovider == COLLPROVIDER_LIBC)
+ locale = collate;
+ else
+ locale = datlocale;
+
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 90f793632a..7419c38722 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -146,6 +146,7 @@ static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
static char *datlocale = NULL;
+static bool icu_locale_specified = false;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -2390,14 +2391,13 @@ setlocales(void)
lc_messages = canonname;
#endif
+ if (locale_provider != COLLPROVIDER_LIBC && datlocale == NULL)
+ pg_fatal("locale must be specified unless provider is libc");
+
if (locale_provider == COLLPROVIDER_ICU)
{
char *langtag;
- /* acquire default locale from the environment, if not specified */
- if (datlocale == NULL)
- pg_fatal("ICU locale must be specified");
-
/* canonicalize to a language tag */
langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
@@ -2442,7 +2442,8 @@ usage(const char *progname)
" set default locale in the respective category for\n"
" new databases (default taken from environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --builtin-locale=LOCALE set builtin locale name for new databases\n"));
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" set default locale provider for new databases\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
printf(_(" -T, --text-search-config=CFG\n"
@@ -2593,20 +2594,28 @@ setup_locale_encoding(void)
{
setlocales();
- if (locale_provider == COLLPROVIDER_LIBC &&
- strcmp(lc_ctype, lc_collate) == 0 &&
- strcmp(lc_ctype, lc_time) == 0 &&
- strcmp(lc_ctype, lc_numeric) == 0 &&
- strcmp(lc_ctype, lc_monetary) == 0 &&
- strcmp(lc_ctype, lc_messages) == 0 &&
- (!datlocale || strcmp(lc_ctype, datlocale) == 0))
+ if (locale_provider == COLLPROVIDER_BUILTIN &&
+ strcmp(lc_ctype, "C") == 0 &&
+ strcmp(lc_collate, "C") == 0 &&
+ strcmp(lc_time, "C") == 0 &&
+ strcmp(lc_numeric, "C") == 0 &&
+ strcmp(lc_monetary, "C") == 0 &&
+ strcmp(lc_messages, "C") == 0)
+ printf(_("The database cluster will be initialized with no locale.\n"));
+ else if (locale_provider == COLLPROVIDER_LIBC &&
+ strcmp(lc_ctype, lc_collate) == 0 &&
+ strcmp(lc_ctype, lc_time) == 0 &&
+ strcmp(lc_ctype, lc_numeric) == 0 &&
+ strcmp(lc_ctype, lc_monetary) == 0 &&
+ strcmp(lc_ctype, lc_messages) == 0 &&
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
- printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (datlocale)
- printf(_(" ICU locale: %s\n"), datlocale);
+ printf(_(" default collation provider: %s\n"), collprovider_name(locale_provider));
+ if (locale_provider != COLLPROVIDER_LIBC)
+ printf(_(" default collation locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3099,9 +3108,10 @@ main(int argc, char *argv[])
{"allow-group-access", no_argument, NULL, 'g'},
{"discard-caches", no_argument, NULL, 14},
{"locale-provider", required_argument, NULL, 15},
- {"icu-locale", required_argument, NULL, 16},
- {"icu-rules", required_argument, NULL, 17},
- {"sync-method", required_argument, NULL, 18},
+ {"builtin-locale", required_argument, NULL, 16},
+ {"icu-locale", required_argument, NULL, 17},
+ {"icu-rules", required_argument, NULL, 18},
+ {"sync-method", required_argument, NULL, 19},
{NULL, 0, NULL, 0}
};
@@ -3269,7 +3279,9 @@ main(int argc, char *argv[])
"-c debug_discard_caches=1");
break;
case 15:
- if (strcmp(optarg, "icu") == 0)
+ if (strcmp(optarg, "builtin") == 0)
+ locale_provider = COLLPROVIDER_BUILTIN;
+ else if (strcmp(optarg, "icu") == 0)
locale_provider = COLLPROVIDER_ICU;
else if (strcmp(optarg, "libc") == 0)
locale_provider = COLLPROVIDER_LIBC;
@@ -3280,9 +3292,13 @@ main(int argc, char *argv[])
datlocale = pg_strdup(optarg);
break;
case 17:
- icu_rules = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
+ icu_locale_specified = true;
break;
case 18:
+ icu_rules = pg_strdup(optarg);
+ break;
+ case 19:
if (!parse_sync_method(optarg, &sync_method))
exit(1);
break;
@@ -3312,7 +3328,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (datlocale && locale_provider != COLLPROVIDER_ICU)
+ if (icu_locale_specified && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 03376cc0f7..242f4581a5 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -117,7 +117,7 @@ if ($ENV{with_icu} eq 'yes')
{
command_fails_like(
[ 'initdb', '--no-sync', '--locale-provider=icu', "$tempdir/data2" ],
- qr/initdb: error: ICU locale must be specified/,
+ qr/initdb: error: locale must be specified unless provider is libc/,
'locale provider ICU requires --icu-locale');
command_ok(
@@ -138,7 +138,7 @@ if ($ENV{with_icu} eq 'yes')
'--lc-monetary=C', '--lc-time=C',
"$tempdir/data4"
],
- qr/^\s+ICU locale:\s+und\n/ms,
+ qr/^\s+default collation locale:\s+und\n/ms,
'options --locale-provider=icu --locale=und --lc-*=C');
command_fails_like(
@@ -184,6 +184,59 @@ else
'locale provider ICU fails since no ICU support');
}
+command_fails(
+ [ 'initdb', '--no-sync', '--locale-provider=builtin', "$tempdir/data6" ],
+ 'locale provider builtin fails without --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--locale=C',
+ "$tempdir/data7"
+ ],
+ 'locale provider builtin with --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E SQL_ASCII',
+ '--builtin-locale=C.UTF-8', "$tempdir/data9"
+ ],
+ 'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
+);
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--lc-ctype=C',
+ '--locale=C', "$tempdir/data10"
+ ],
+ 'locale provider builtin with --lc-ctype');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-locale=en',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU locale');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-rules=""',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU rules');
+
command_fails(
[ 'initdb', '--no-sync', '--locale-provider=xyz', "$tempdir/dataX" ],
'fails for invalid locale provider');
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index a67b4b8225..450c322205 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3114,7 +3114,9 @@ dumpDatabase(Archive *fout)
}
appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
- if (datlocprovider[0] == 'c')
+ if (datlocprovider[0] == 'b')
+ appendPQExpBufferStr(creaQry, "builtin");
+ else if (datlocprovider[0] == 'c')
appendPQExpBufferStr(creaQry, "libc");
else if (datlocprovider[0] == 'i')
appendPQExpBufferStr(creaQry, "icu");
@@ -3122,27 +3124,33 @@ dumpDatabase(Archive *fout)
pg_fatal("unrecognized locale provider: %s",
datlocprovider);
- if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ if (!locale && datlocprovider[0] != 'c')
+ pg_log_warning("database '%s' with provider '%s' missing datlocale",
+ datname, datlocprovider);
+
+ if (locale && datlocprovider[0] == 'c')
+ pg_log_warning("database '%s' with provider 'c' has non-NULL locale '%s'",
+ datname, locale);
+
+ /* if collate and ctype are equal, and locale is NULL, use LOCALE */
+ if (!locale && strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ locale = collate;
+
+ /* output LC_COLLATE and LC_CTYPE if different from LOCALE */
+ if (strlen(collate) > 0 && (!locale || strcmp(collate, locale) != 0))
{
- appendPQExpBufferStr(creaQry, " LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
appendStringLiteralAH(creaQry, collate, fout);
}
- else
+ if (strlen(ctype) > 0 && (!locale || strcmp(ctype, locale) != 0))
{
- if (strlen(collate) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
- appendStringLiteralAH(creaQry, collate, fout);
- }
- if (strlen(ctype) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
- appendStringLiteralAH(creaQry, ctype, fout);
- }
+ appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+ appendStringLiteralAH(creaQry, ctype, fout);
}
+
if (locale)
{
- appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LOCALE = ");
appendStringLiteralAH(creaQry, locale, fout);
}
@@ -13870,7 +13878,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
fmtQualifiedDumpable(collinfo));
appendPQExpBufferStr(q, "provider = ");
- if (collprovider[0] == 'c')
+ if (collprovider[0] == 'b')
+ appendPQExpBufferStr(q, "builtin");
+ else if (collprovider[0] == 'c')
appendPQExpBufferStr(q, "libc");
else if (collprovider[0] == 'i')
appendPQExpBufferStr(q, "icu");
@@ -13891,6 +13901,13 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
/* no locale -- the default collation cannot be reloaded anyway */
}
+ else if (collprovider[0] == 'b')
+ {
+ if (collcollate || collctype || colllocale || collicurules)
+ pg_log_warning("invalid collation \"%s\"", qcollname);
+
+ appendPQExpBufferStr(q, ", locale = 'C'");
+ }
else if (collprovider[0] == 'i')
{
if (fout->remoteVersion >= 150000)
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index 41d06d272b..94bf086ba8 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -110,13 +110,16 @@ my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
-my $original_encoding = "6"; # UTF-8
-my $original_provider = "c";
-my $original_locale = "C";
-my $original_datlocale = "";
-my $provider_field = "'c' AS datlocprovider";
-my $datlocale_field = "NULL AS datlocale";
-if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+my %encoding_number = ('UTF-8' => 6, 'SQL_ASCII' => 0);
+my $provider_field;
+my $datlocale_field;
+my $original_encoding;
+my $original_provider;
+my $original_datcollate = "C";
+my $original_datctype = "C";
+my $original_datlocale;
+
+if ($oldversion >= 15)
{
$provider_field = "datlocprovider";
if ($oldversion >= 17)
@@ -127,18 +130,52 @@ if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$datlocale_field = "daticulocale AS datlocale";
}
+}
+else
+{
+ $provider_field = "'c' AS datlocprovider";
+ $datlocale_field = "NULL AS datlocale";
+}
+
+if ($oldversion >= 17)
+{
+ $original_encoding = "UTF-8";
+ $original_provider = "b";
+ $original_datlocale = "C.UTF-8";
+}
+elsif ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+{
+ $original_encoding = "UTF-8";
$original_provider = "i";
$original_datlocale = "fr-CA";
}
+else
+{
+ my $original_encoding = "SQL_ASCII";
+ my $original_provider = "c";
+ my $original_datlocale = "";
+}
my @initdb_params = @custom_opts;
-push @initdb_params, ('--encoding', 'UTF-8');
-push @initdb_params, ('--locale', $original_locale);
-if ($original_provider eq "i")
+push @initdb_params, ('--encoding', $original_encoding);
+push @initdb_params, ('--lc-collate', $original_datcollate);
+push @initdb_params, ('--lc-ctype', $original_datctype);
+
+# add --locale-provider, if supported
+my %provider_name = ('b' => 'builtin', 'i' => 'icu', 'c' => 'libc');
+if ($oldnode->pg_version >= 15)
{
- push @initdb_params, ('--locale-provider', 'icu');
- push @initdb_params, ('--icu-locale', 'fr-CA');
+ push @initdb_params,
+ ('--locale-provider', $provider_name{$original_provider});
+ if ($original_provider eq 'b')
+ {
+ push @initdb_params, ('--builtin-locale', $original_datlocale);
+ }
+ elsif ($original_provider eq 'i')
+ {
+ push @initdb_params, ('--icu-locale', $original_datlocale);
+ }
}
$node_params{extra} = \@initdb_params;
@@ -151,7 +188,7 @@ $result = $oldnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -327,7 +364,8 @@ if (defined($ENV{oldinstall}))
}
# Create an invalid database, will be deleted below
-$oldnode->safe_psql('postgres', qq(
+$oldnode->safe_psql(
+ 'postgres', qq(
CREATE DATABASE regression_invalid;
UPDATE pg_database SET datconnlimit = -2 WHERE datname = 'regression_invalid';
));
@@ -370,7 +408,7 @@ command_checks_all(
$mode, '--check',
],
1,
- [qr/invalid/], # pg_upgrade prints errors on stdout :(
+ [qr/invalid/], # pg_upgrade prints errors on stdout :(
[qr//],
'invalid database causes failure');
rmtree($newnode->data_dir . "/pg_upgrade_output.d");
@@ -434,7 +472,7 @@ $result = $newnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index b943569050..c649477505 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -926,7 +926,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Encoding"));
if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
- " CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE d.datlocprovider WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Locale Provider"));
else
appendPQExpBuffer(&buf,
@@ -4974,7 +4974,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
if (pset.sversion >= 100000)
appendPQExpBuffer(&buf,
- " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Provider"));
else
appendPQExpBuffer(&buf,
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
index 14970a6a5f..4af4b98181 100644
--- a/src/bin/scripts/createdb.c
+++ b/src/bin/scripts/createdb.c
@@ -40,8 +40,9 @@ main(int argc, char *argv[])
{"locale", required_argument, NULL, 'l'},
{"maintenance-db", required_argument, NULL, 3},
{"locale-provider", required_argument, NULL, 4},
- {"icu-locale", required_argument, NULL, 5},
- {"icu-rules", required_argument, NULL, 6},
+ {"builtin-locale", required_argument, NULL, 5},
+ {"icu-locale", required_argument, NULL, 6},
+ {"icu-rules", required_argument, NULL, 7},
{NULL, 0, NULL, 0}
};
@@ -67,6 +68,7 @@ main(int argc, char *argv[])
char *lc_ctype = NULL;
char *locale = NULL;
char *locale_provider = NULL;
+ char *builtin_locale = NULL;
char *icu_locale = NULL;
char *icu_rules = NULL;
@@ -134,9 +136,12 @@ main(int argc, char *argv[])
locale_provider = pg_strdup(optarg);
break;
case 5:
- icu_locale = pg_strdup(optarg);
+ builtin_locale = pg_strdup(optarg);
break;
case 6:
+ icu_locale = pg_strdup(optarg);
+ break;
+ case 7:
icu_rules = pg_strdup(optarg);
break;
default:
@@ -216,6 +221,11 @@ main(int argc, char *argv[])
appendPQExpBufferStr(&sql, " LOCALE ");
appendStringLiteralConn(&sql, locale, conn);
}
+ if (builtin_locale)
+ {
+ appendPQExpBufferStr(&sql, " BUILTIN_LOCALE ");
+ appendStringLiteralConn(&sql, builtin_locale, conn);
+ }
if (lc_collate)
{
appendPQExpBufferStr(&sql, " LC_COLLATE ");
@@ -296,7 +306,7 @@ help(const char *progname)
printf(_(" --lc-ctype=LOCALE LC_CTYPE setting for the database\n"));
printf(_(" --icu-locale=LOCALE ICU locale setting for the database\n"));
printf(_(" --icu-rules=RULES ICU rules setting for the database\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" locale provider for the database's default collation\n"));
printf(_(" -O, --owner=OWNER database user to own the new database\n"));
printf(_(" -S, --strategy=STRATEGY database creation strategy wal_log or file_copy\n"));
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index 37e47b0078..3ba623f9d1 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -105,6 +105,84 @@ else
'create database with ICU fails since no ICU support');
}
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ 'tbuiltin1'
+ ],
+ 'create database with provider "builtin" fails without --locale');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin2'
+ ],
+ 'create database with provider "builtin" and locale "C"');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-collate=C',
+ 'tbuiltin3'
+ ],
+ 'create database with provider "builtin" and LC_COLLATE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-ctype=C',
+ 'tbuiltin4'
+ ],
+ 'create database with provider "builtin" and LC_CTYPE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E UTF-8', '--builtin-locale=C.UTF8',
+ 'tbuiltin5'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E LATIN1', '--builtin-locale=C.UTF-8',
+ 'tbuiltin6'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-locale=en',
+ 'tbuiltin7'
+ ],
+ 'create database with provider "builtin" and ICU_LOCALE="en"');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-rules=""',
+ 'tbuiltin8'
+ ],
+ 'create database with provider "builtin" and ICU_RULES=""');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template1', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin9'
+ ],
+ 'create database with provider "builtin" not matching template');
+
$node->command_fails([ 'createdb', 'foobar1' ],
'fails if database already exists');
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 7396ff10c4..938432e8a4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -23,9 +23,9 @@
descr => 'standard POSIX collation',
collname => 'POSIX', collprovider => 'c', collencoding => '-1',
collcollate => 'POSIX', collctype => 'POSIX' },
-{ oid => '962', descr => 'sorts by Unicode code point',
- collname => 'ucs_basic', collprovider => 'c', collencoding => '6',
- collcollate => 'C', collctype => 'C' },
+{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',
+ collname => 'ucs_basic', collprovider => 'b', collencoding => '6',
+ colllocale => 'C' },
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index a3e196fb53..5ce289d74b 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -68,6 +68,7 @@ MAKE_SYSCACHE(COLLOID, pg_collation_oid_index, 8);
#ifdef EXPOSE_TO_CLIENT_CODE
#define COLLPROVIDER_DEFAULT 'd'
+#define COLLPROVIDER_BUILTIN 'b'
#define COLLPROVIDER_ICU 'i'
#define COLLPROVIDER_LIBC 'c'
@@ -76,6 +77,8 @@ collprovider_name(char c)
{
switch (c)
{
+ case COLLPROVIDER_BUILTIN:
+ return "builtin";
case COLLPROVIDER_ICU:
return "icu";
case COLLPROVIDER_LIBC:
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 28c925b5af..4dfcb99872 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -76,6 +76,13 @@ struct pg_locale_struct
bool deterministic;
union
{
+ struct
+ {
+ const char *locale;
+ bool casemap_full;
+ bool titlecase;
+ bool properties_posix;
+ } builtin;
locale_t lt;
#ifdef USE_ICU
struct
@@ -112,7 +119,7 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
pg_locale_t locale);
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
size_t srclen, pg_locale_t locale);
-
+extern const char *builtin_validate_locale(int encoding, const char *loc_str);
extern void icu_validate_locale(const char *loc_str);
extern char *icu_language_tag(const char *loc_str, int elevel);
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
index 8a1fc12ec6..5f8ef16803 100644
--- a/src/test/icu/t/010_database.pl
+++ b/src/test/icu/t/010_database.pl
@@ -27,9 +27,8 @@ CREATE TABLE icu (def text, en text COLLATE "en-x-icu", upfirst text COLLATE upp
INSERT INTO icu VALUES ('a', 'a', 'a'), ('b', 'b', 'b'), ('A', 'A', 'A'), ('B', 'B', 'B');
});
-is( $node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
- qq(t),
- 'ICU unicode version defined');
+is($node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
+ qq(t), 'ICU unicode version defined');
is( $node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY def}),
qq(A
@@ -63,14 +62,13 @@ is( $node1->psql(
0,
"C locale works for ICU");
-# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
-# are specified
-is( $node1->psql(
- 'postgres',
- q{CREATE DATABASE dbicu2 LOCALE_PROVIDER icu LOCALE '@colStrength=primary'
- LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0 ENCODING UTF8}
- ),
- 0,
- "LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE are specified");
+my ($ret, $stdout, $stderr) = $node1->psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
+);
+isnt($ret, 0, "locale provider must match template: exit code not 0");
+like(
+ $stderr,
+ qr/ERROR: new locale provider \(builtin\) does not match locale provider of the template database \(icu\)/,
+ "locale provider must match template: error message");
done_testing();
diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out
index 0649564485..ece4a8e99d 100644
--- a/src/test/regress/expected/collate.out
+++ b/src/test/regress/expected/collate.out
@@ -650,6 +650,26 @@ EXPLAIN (COSTS OFF)
(3 rows)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+ b
+-----
+ ABD
+ Abc
+ abc
+ bbc
+(4 rows)
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+ERROR: invalid locale name "en_US" for builtin provider
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+ERROR: conflicting or redundant options
+DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
@@ -754,7 +774,7 @@ DETAIL: FROM cannot be specified together with any other options.
-- must get rid of them.
--
DROP SCHEMA collate_tests CASCADE;
-NOTICE: drop cascades to 19 other objects
+NOTICE: drop cascades to 21 other objects
DETAIL: drop cascades to table collate_test1
drop cascades to table collate_test_like
drop cascades to table collate_test2
@@ -771,6 +791,8 @@ drop cascades to function dup(anyelement)
drop cascades to table collate_test20
drop cascades to table collate_test21
drop cascades to table collate_test22
+drop cascades to collation builtin_c
+drop cascades to collation builtin_posix
drop cascades to collation mycoll2
drop cascades to table collate_test23
drop cascades to view collate_on_int
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
new file mode 100644
index 0000000000..ecf5305105
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8.out
@@ -0,0 +1,288 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+SET client_encoding TO UTF8;
+--
+-- Test builtin PG_UNICODE_FAST locale.
+--
+CREATE COLLATION BUILTIN_UNICODE_FAST
+ ( provider = builtin, locale = 'PG_UNICODE_FAST' );
+CREATE TABLE builtin_test1 (
+ t TEXT COLLATE BUILTIN_UNICODE_FAST
+);
+INSERT INTO builtin_test1 VALUES
+ ('abc DEF'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test1;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF | abc def | Abc Def | ABC DEF | 7 | 7 | 7 | 7
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE builtin_test1;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
+DROP COLLATION BUILTIN_UNICODE_FAST;
+--
+-- Test builtin C.UTF-8 locale.
+--
+CREATE COLLATION BUILTIN_C_UTF8 ( provider = builtin, locale = 'C.UTF-8' );
+CREATE TABLE builtin_test2 (
+ t TEXT COLLATE BUILTIN_C_UTF8
+);
+INSERT INTO builtin_test2 VALUES
+ ('abc DEF'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test2;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+-----------------+-----------------+---------+---------------+-----------------+---------------
+ abc DEF | abc def | Abc Def | ABC DEF | 7 | 7 | 7 | 7
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs ßss Déf | ÁBC SßS ßSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | DŽxxdž DŽxxdž DŽxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE builtin_test2;
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ ασ
+(1 row)
+
+SELECT lower('ΑͺΣͺ' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ αͺσͺ
+(1 row)
+
+SELECT lower('Α΄Σ΄' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ α΄σ΄
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' ~ '[[:punct:]]' COLLATE BUILTIN_C_UTF8; -- symbols are punctuation in posix
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' !~ '\d' COLLATE BUILTIN_C_UTF8; -- only 0-9 considered digits in posix
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_C_UTF8; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
+DROP COLLATION BUILTIN_C_UTF8;
diff --git a/src/test/regress/expected/collate.utf8_1.out b/src/test/regress/expected/collate.utf8_1.out
new file mode 100644
index 0000000000..e73fdf50c3
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8_1.out
@@ -0,0 +1,8 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 1d8a414eea..e48cb4b7a3 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,9 +78,9 @@ test: brin_bloom brin_multi
# psql depends on create_am
# amutils depends on geometry, create_index_spgist, hash_index, brin
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps
-# collate.*.utf8 tests cannot be run in parallel with each other
+# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252
# ----------
diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql
index c3d40fc195..01d5c69fe4 100644
--- a/src/test/regress/sql/collate.sql
+++ b/src/test/regress/sql/collate.sql
@@ -244,6 +244,16 @@ EXPLAIN (COSTS OFF)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
new file mode 100644
index 0000000000..c0da1e7cb4
--- /dev/null
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -0,0 +1,123 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+SET client_encoding TO UTF8;
+
+--
+-- Test builtin PG_UNICODE_FAST locale.
+--
+
+CREATE COLLATION BUILTIN_UNICODE_FAST
+ ( provider = builtin, locale = 'PG_UNICODE_FAST' );
+
+CREATE TABLE builtin_test1 (
+ t TEXT COLLATE BUILTIN_UNICODE_FAST
+);
+INSERT INTO builtin_test1 VALUES
+ ('abc DEF'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test1;
+
+DROP TABLE builtin_test1;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
+
+DROP COLLATION BUILTIN_UNICODE_FAST;
+
+--
+-- Test builtin C.UTF-8 locale.
+--
+
+CREATE COLLATION BUILTIN_C_UTF8 ( provider = builtin, locale = 'C.UTF-8' );
+
+CREATE TABLE builtin_test2 (
+ t TEXT COLLATE BUILTIN_C_UTF8
+);
+INSERT INTO builtin_test2 VALUES
+ ('abc DEF'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test2;
+
+DROP TABLE builtin_test2;
+
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE BUILTIN_C_UTF8);
+SELECT lower('ΑͺΣͺ' COLLATE BUILTIN_C_UTF8);
+SELECT lower('Α΄Σ΄' COLLATE BUILTIN_C_UTF8);
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '=' ~ '[[:punct:]]' COLLATE BUILTIN_C_UTF8; -- symbols are punctuation in posix
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '൧' !~ '\d' COLLATE BUILTIN_C_UTF8; -- only 0-9 considered digits in posix
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_C_UTF8;
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_C_UTF8;
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_C_UTF8;
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_C_UTF8;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_C_UTF8; -- same as above with cases reversed
+
+DROP COLLATION BUILTIN_C_UTF8;
--
2.34.1
[text/x-patch] v19-0006-Add-builtin-collation-objects-PG_C_UTF8-and-PG_U.patch (10.7K, ../../[email protected]/7-v19-0006-Add-builtin-collation-objects-PG_C_UTF8-and-PG_U.patch)
download | inline diff:
From afefb373f8777f772c34f1b2daec88a33de74eb1 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 19 Feb 2024 14:43:15 -0800
Subject: [PATCH v19 6/6] Add builtin collation objects PG_C_UTF8 and
PG_UNICODE_FAST.
---
doc/src/sgml/charset.sgml | 34 ++++++++++++++++
src/include/catalog/pg_collation.dat | 6 +++
src/test/regress/expected/collate.utf8.out | 45 ++++++++++-----------
src/test/regress/sql/collate.utf8.sql | 47 ++++++++++------------
4 files changed, 82 insertions(+), 50 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 2abd898115..47f137e1f0 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -874,6 +874,40 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>PG_C_UTF8</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point. Behavior is efficient and
+ stable within a <productname>Postgres</productname> major version.
+ For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode simple case mapping. For pattern matching (including regular
+ expressions), it uses the POSIX Compatible variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. This collation is only available for encoding
+ <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PG_UNICODE_FAST</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point. Behavior is efficient and
+ stable within a <productname>Postgres</productname> major version.
+ For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. It is only available for encoding
+ <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
<listitem>
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 938432e8a4..a187b3dcef 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -30,5 +30,11 @@
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
+{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
+ collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
+ colllocale => 'C.UTF-8' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST' },
]
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index ecf5305105..14cbc0f870 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -11,10 +11,8 @@ SET client_encoding TO UTF8;
--
-- Test builtin PG_UNICODE_FAST locale.
--
-CREATE COLLATION BUILTIN_UNICODE_FAST
- ( provider = builtin, locale = 'PG_UNICODE_FAST' );
CREATE TABLE builtin_test1 (
- t TEXT COLLATE BUILTIN_UNICODE_FAST
+ t TEXT COLLATE PG_UNICODE_FAST
);
INSERT INTO builtin_test1 VALUES
('abc DEF'),
@@ -42,130 +40,129 @@ SELECT
DROP TABLE builtin_test1;
-- test Final_Sigma
-SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
lower
-------
ας
(1 row)
-SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
lower
-------
ας0
(1 row)
-SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
lower
-------
ἀς̓
(1 row)
-SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
lower
-------
ᾳςͅ
(1 row)
-- test !Final_Sigma
-SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
lower
-------
σ
(1 row)
-SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
lower
-------
0σ
(1 row)
-SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
lower
-------
ασα
(1 row)
-SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
lower
-------
ἀσ̓α
(1 row)
-SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
lower
-------
ᾳσͅα
(1 row)
-- properties
-SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
?column?
----------
t
(1 row)
-SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-- case mapping
-SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
?column?
----------
t
(1 row)
-DROP COLLATION BUILTIN_UNICODE_FAST;
--
-- Test builtin C.UTF-8 locale.
--
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index c0da1e7cb4..0c799b24a2 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -15,11 +15,8 @@ SET client_encoding TO UTF8;
-- Test builtin PG_UNICODE_FAST locale.
--
-CREATE COLLATION BUILTIN_UNICODE_FAST
- ( provider = builtin, locale = 'PG_UNICODE_FAST' );
-
CREATE TABLE builtin_test1 (
- t TEXT COLLATE BUILTIN_UNICODE_FAST
+ t TEXT COLLATE PG_UNICODE_FAST
);
INSERT INTO builtin_test1 VALUES
('abc DEF'),
@@ -40,36 +37,34 @@ SELECT
DROP TABLE builtin_test1;
-- test Final_Sigma
-SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
-SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
-SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
-SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
-- test !Final_Sigma
-SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
-SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
-SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
-SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
-SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
-- properties
-SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
-SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
-- case mapping
-SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
-
-DROP COLLATION BUILTIN_UNICODE_FAST;
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
-- Test builtin C.UTF-8 locale.
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-02 23:02 ` Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-02 23:02 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Thu, 2024-02-29 at 21:05 -0800, Jeff Davis wrote:
> Attached v19 which addresses this issue.
I pushed the doc patch.
Attached v20. I am going to start pushing some other patches. v20-0001
(property tables) and v20-0003 (catalog iculocale -> locale) have been
stable for a while so are likely to go in soon. v20-0002 (case mapping)
also feels close to me, but it went through significant changes to
support full case mapping and titlecasing, so I'll see if there are
more comments.
Changes in v20:
* For titlecasing with the builtin "C.UTF-8" locale, do not perform
word break adjustment, so it matches libc's "C.UTF-8" titlecasing
behavior more closely.
* Add optimized table for ASCII code points when determining
categories and properties (this was already done for the case mapping
table).
* Add a small patch to make UTF-8 functions inline, which speeds
things up substantially.
Performance:
ASCII-only data:
lower initcap upper
"C" (libc) 2426 3326 2341
pg_c_utf8 2890 6570 2825
pg_unicode_fast 2929 7140 2893
"C.utf8" (libc) 5410 7810 5397
"en-US-x-icu" 8320 65732 9367
Including non-ASCII data:
lower initcap upper
"C" (libc) 2630 4677 2548
pg_c_utf8 5471 10682 5431
pg_unicode_fast 5582 12023 5587
"C.utf8" (libc) 8126 11834 8106
"en-US-x-icu" 14473 73655 15112
The new builtin collations nicely finish ahead of everything except "C"
(with an exception where pg_unicode_fast is marginally slower at
titlecasing non-ASCII data than libc "C.UTF-8", which is likely due to
the word break adjustment semantics).
I suspect the inlined UTF-8 functions also speed up a few other areas,
but I didn't measure.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v20-0001-Add-Unicode-property-tables.patch (121.6K, ../../[email protected]/2-v20-0001-Add-Unicode-property-tables.patch)
download | inline diff:
From ffd7182d48a0a0f1c04b0810ef5a1b28252e26d0 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 18 Nov 2023 15:34:24 -0800
Subject: [PATCH v20 1/6] Add Unicode property tables.
Provide functions to test for regex character classes (e.g. 'alpha',
'punct') using Unicode properties.
---
src/common/unicode/Makefile | 6 +-
src/common/unicode/category_test.c | 225 +-
.../generate-unicode_category_table.pl | 389 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_category.c | 318 +-
src/include/common/unicode_category.h | 27 +-
src/include/common/unicode_category_table.h | 3566 ++++++++++++++++-
7 files changed, 4441 insertions(+), 94 deletions(-)
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index 04d81dd5cb..27f0408d8b 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -29,13 +29,13 @@ update-unicode: unicode_category_table.h unicode_east_asian_fw_table.h unicode_n
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
$(PERL) $< --version $(UNICODE_VERSION)
-unicode_category_table.h: generate-unicode_category_table.pl UnicodeData.txt
+unicode_category_table.h: generate-unicode_category_table.pl DerivedCoreProperties.txt PropList.txt UnicodeData.txt
$(PERL) $<
# Generation of conversion tables used for string normalization with
@@ -82,4 +82,4 @@ clean:
rm -f $(OBJS) category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/category_test.c b/src/common/unicode/category_test.c
index f1aaac0f61..8d1732b448 100644
--- a/src/common/unicode/category_test.c
+++ b/src/common/unicode/category_test.c
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------
* category_test.c
- * Program to test Unicode general category functions.
+ * Program to test Unicode general category and character properties.
*
* Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
*
@@ -14,17 +14,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
#ifdef USE_ICU
#include <unicode/uchar.h>
#endif
-#include "common/unicode_category.h"
+#include <wctype.h>
+
#include "common/unicode_version.h"
+#include "common/unicode_category.h"
+
+static int pg_unicode_version = 0;
+#ifdef USE_ICU
+static int icu_unicode_version = 0;
+#endif
/*
* Parse version into integer for easy comparison.
*/
-#ifdef USE_ICU
static int
parse_unicode_version(const char *version)
{
@@ -39,57 +44,175 @@ parse_unicode_version(const char *version)
return major * 100 + minor;
}
-#endif
+#ifdef USE_ICU
/*
- * Exhaustively test that the Unicode category for each codepoint matches that
- * returned by ICU.
+ * Test Postgres Unicode tables by comparing with ICU. Test the General
+ * Category, as well as the properties Alphabetic, Lowercase, Uppercase,
+ * White_Space, and Hex_Digit.
*/
-int
-main(int argc, char **argv)
+static void
+icu_test()
{
-#ifdef USE_ICU
- int pg_unicode_version = parse_unicode_version(PG_UNICODE_VERSION);
- int icu_unicode_version = parse_unicode_version(U_UNICODE_VERSION);
+ int successful = 0;
int pg_skipped_codepoints = 0;
int icu_skipped_codepoints = 0;
- printf("category_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
- printf("category_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
-
- for (UChar32 code = 0; code <= 0x10ffff; code++)
+ for (pg_wchar code = 0; code <= 0x10ffff; code++)
{
uint8_t pg_category = unicode_category(code);
uint8_t icu_category = u_charType(code);
+ /* Property tests */
+ bool prop_alphabetic = pg_u_prop_alphabetic(code);
+ bool prop_lowercase = pg_u_prop_lowercase(code);
+ bool prop_uppercase = pg_u_prop_uppercase(code);
+ bool prop_cased = pg_u_prop_cased(code);
+ bool prop_case_ignorable = pg_u_prop_case_ignorable(code);
+ bool prop_white_space = pg_u_prop_white_space(code);
+ bool prop_hex_digit = pg_u_prop_hex_digit(code);
+ bool prop_join_control = pg_u_prop_join_control(code);
+
+ bool icu_prop_alphabetic = u_hasBinaryProperty(
+ code, UCHAR_ALPHABETIC);
+ bool icu_prop_lowercase = u_hasBinaryProperty(
+ code, UCHAR_LOWERCASE);
+ bool icu_prop_uppercase = u_hasBinaryProperty(
+ code, UCHAR_UPPERCASE);
+ bool icu_prop_cased = u_hasBinaryProperty(
+ code, UCHAR_CASED);
+ bool icu_prop_case_ignorable = u_hasBinaryProperty(
+ code, UCHAR_CASE_IGNORABLE);
+ bool icu_prop_white_space = u_hasBinaryProperty(
+ code, UCHAR_WHITE_SPACE);
+ bool icu_prop_hex_digit = u_hasBinaryProperty(
+ code, UCHAR_HEX_DIGIT);
+ bool icu_prop_join_control = u_hasBinaryProperty(
+ code, UCHAR_JOIN_CONTROL);
+
+ /*
+ * Compare with ICU for character classes using:
+ *
+ * https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/uchar_8h.html#details
+ *
+ * which describes how to use ICU to test for membership in regex
+ * character classes.
+ *
+ * NB: the document suggests testing for some properties such as
+ * UCHAR_POSIX_ALNUM, but that doesn't mean that we're testing for the
+ * "POSIX Compatible" character classes.
+ */
+ bool isalpha = pg_u_isalpha(code);
+ bool islower = pg_u_islower(code);
+ bool isupper = pg_u_isupper(code);
+ bool ispunct = pg_u_ispunct(code, false);
+ bool isdigit = pg_u_isdigit(code, false);
+ bool isxdigit = pg_u_isxdigit(code, false);
+ bool isalnum = pg_u_isalnum(code, false);
+ bool isspace = pg_u_isspace(code);
+ bool isblank = pg_u_isblank(code);
+ bool iscntrl = pg_u_iscntrl(code);
+ bool isgraph = pg_u_isgraph(code);
+ bool isprint = pg_u_isprint(code);
+
+ bool icu_isalpha = u_isUAlphabetic(code);
+ bool icu_islower = u_isULowercase(code);
+ bool icu_isupper = u_isUUppercase(code);
+ bool icu_ispunct = u_ispunct(code);
+ bool icu_isdigit = u_isdigit(code);
+ bool icu_isxdigit = u_hasBinaryProperty(code,
+ UCHAR_POSIX_XDIGIT);
+ bool icu_isalnum = u_hasBinaryProperty(code,
+ UCHAR_POSIX_ALNUM);
+ bool icu_isspace = u_isUWhiteSpace(code);
+ bool icu_isblank = u_isblank(code);
+ bool icu_iscntrl = icu_category == PG_U_CONTROL;
+ bool icu_isgraph = u_hasBinaryProperty(code,
+ UCHAR_POSIX_GRAPH);
+ bool icu_isprint = u_hasBinaryProperty(code,
+ UCHAR_POSIX_PRINT);
+
+ /*
+ * A version mismatch means that some assigned codepoints in the newer
+ * version may be unassigned in the older version. That's OK, though
+ * the test will not cover those codepoints marked unassigned in the
+ * older version (that is, it will no longer be an exhaustive test).
+ */
+ if (pg_category == PG_U_UNASSIGNED &&
+ icu_category != PG_U_UNASSIGNED &&
+ pg_unicode_version < icu_unicode_version)
+ {
+ pg_skipped_codepoints++;
+ continue;
+ }
+
+ if (icu_category == PG_U_UNASSIGNED &&
+ pg_category != PG_U_UNASSIGNED &&
+ icu_unicode_version < pg_unicode_version)
+ {
+ icu_skipped_codepoints++;
+ continue;
+ }
+
if (pg_category != icu_category)
{
- /*
- * A version mismatch means that some assigned codepoints in the
- * newer version may be unassigned in the older version. That's
- * OK, though the test will not cover those codepoints marked
- * unassigned in the older version (that is, it will no longer be
- * an exhaustive test).
- */
- if (pg_category == PG_U_UNASSIGNED &&
- pg_unicode_version < icu_unicode_version)
- pg_skipped_codepoints++;
- else if (icu_category == PG_U_UNASSIGNED &&
- icu_unicode_version < pg_unicode_version)
- icu_skipped_codepoints++;
- else
- {
- printf("category_test: FAILURE for codepoint 0x%06x\n", code);
- printf("category_test: Postgres category: %02d %s %s\n", pg_category,
- unicode_category_abbrev(pg_category),
- unicode_category_string(pg_category));
- printf("category_test: ICU category: %02d %s %s\n", icu_category,
- unicode_category_abbrev(icu_category),
- unicode_category_string(icu_category));
- printf("\n");
- exit(1);
- }
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres category: %02d %s %s\n", pg_category,
+ unicode_category_abbrev(pg_category),
+ unicode_category_string(pg_category));
+ printf("category_test: ICU category: %02d %s %s\n", icu_category,
+ unicode_category_abbrev(icu_category),
+ unicode_category_string(icu_category));
+ printf("\n");
+ exit(1);
}
+
+ if (prop_alphabetic != icu_prop_alphabetic ||
+ prop_lowercase != icu_prop_lowercase ||
+ prop_uppercase != icu_prop_uppercase ||
+ prop_cased != icu_prop_cased ||
+ prop_case_ignorable != icu_prop_case_ignorable ||
+ prop_white_space != icu_prop_white_space ||
+ prop_hex_digit != icu_prop_hex_digit ||
+ prop_join_control != icu_prop_join_control)
+ {
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres property alphabetic/lowercase/uppercase/cased/case_ignorable/white_space/hex_digit/join_control: %d/%d/%d/%d/%d/%d/%d/%d\n",
+ prop_alphabetic, prop_lowercase, prop_uppercase,
+ prop_cased, prop_case_ignorable,
+ prop_white_space, prop_hex_digit, prop_join_control);
+ printf("category_test: ICU property alphabetic/lowercase/uppercase/cased/case_ignorable/white_space/hex_digit/join_control: %d/%d/%d/%d/%d/%d/%d/%d\n",
+ icu_prop_alphabetic, icu_prop_lowercase, icu_prop_uppercase,
+ icu_prop_cased, icu_prop_case_ignorable,
+ icu_prop_white_space, icu_prop_hex_digit, icu_prop_join_control);
+ printf("\n");
+ exit(1);
+ }
+
+ if (isalpha != icu_isalpha ||
+ islower != icu_islower ||
+ isupper != icu_isupper ||
+ ispunct != icu_ispunct ||
+ isdigit != icu_isdigit ||
+ isxdigit != icu_isxdigit ||
+ isalnum != icu_isalnum ||
+ isspace != icu_isspace ||
+ isblank != icu_isblank ||
+ iscntrl != icu_iscntrl ||
+ isgraph != icu_isgraph ||
+ isprint != icu_isprint)
+ {
+ printf("category_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("category_test: Postgres class alpha/lower/upper/punct/digit/xdigit/alnum/space/blank/cntrl/graph/print: %d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n",
+ isalpha, islower, isupper, ispunct, isdigit, isxdigit, isalnum, isspace, isblank, iscntrl, isgraph, isprint);
+ printf("category_test: ICU class alpha/lower/upper/punct/digit/xdigit/alnum/space/blank/cntrl/graph/print: %d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d\n",
+ icu_isalpha, icu_islower, icu_isupper, icu_ispunct, icu_isdigit, icu_isxdigit, icu_isalnum, icu_isspace, icu_isblank, icu_iscntrl, icu_isgraph, icu_isprint);
+ printf("\n");
+ exit(1);
+ }
+
+ if (pg_category != PG_U_UNASSIGNED)
+ successful++;
}
if (pg_skipped_codepoints > 0)
@@ -99,10 +222,22 @@ main(int argc, char **argv)
printf("category_test: skipped %d codepoints unassigned in ICU due to Unicode version mismatch\n",
icu_skipped_codepoints);
- printf("category_test: success\n");
- exit(0);
+ printf("category_test: ICU test: %d codepoints successful\n", successful);
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+ pg_unicode_version = parse_unicode_version(PG_UNICODE_VERSION);
+ printf("category_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
+
+#ifdef USE_ICU
+ icu_unicode_version = parse_unicode_version(U_UNICODE_VERSION);
+ printf("category_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
+
+ icu_test();
#else
- printf("category_test: ICU support required for test; skipping\n");
- exit(0);
+ printf("category_test: ICU not available; skipping\n");
#endif
}
diff --git a/src/common/unicode/generate-unicode_category_table.pl b/src/common/unicode/generate-unicode_category_table.pl
index a50c87b7e9..5151018aa6 100644
--- a/src/common/unicode/generate-unicode_category_table.pl
+++ b/src/common/unicode/generate-unicode_category_table.pl
@@ -25,6 +25,10 @@ my $output_table_file = "$output_path/unicode_category_table.h";
my $FH;
+# create a table of all codepoints < 0x80 and their associated
+# categories and properties for fast lookups
+my %opt_ascii = ();
+
# Read entries from UnicodeData.txt into a list of codepoint ranges
# and their general category.
my @category_ranges = ();
@@ -48,21 +52,42 @@ while (my $line = <$FH>)
my $category = $elts[2];
die "codepoint out of range" if $code > 0x10FFFF;
- die "unassigned codepoint in UnicodeData.txt" if $category eq $CATEGORY_UNASSIGNED;
+ die "unassigned codepoint in UnicodeData.txt"
+ if $category eq $CATEGORY_UNASSIGNED;
+
+ if ($code < 0x80)
+ {
+ my @properties = ();
+ # No ASCII characters have category Titlecase_Letter,
+ # but include here for completeness.
+ push @properties, "PG_U_PROP_CASED" if ($category eq 'Lt');
+ $opt_ascii{$code} = {
+ Category => $category,
+ Properties => \@properties
+ };
+ }
- if (!defined($range_start)) {
+ if (!defined($range_start))
+ {
my $code_str = sprintf "0x%06x", $code;
- die if defined($range_end) || defined($range_category) || defined($gap_category);
+ die
+ if defined($range_end)
+ || defined($range_category)
+ || defined($gap_category);
die "unexpected first entry <..., Last>" if ($name =~ /Last>/);
- die "expected 0x000000 for first entry, got $code_str" if $code != 0x000000;
+ die "expected 0x000000 for first entry, got $code_str"
+ if $code != 0x000000;
# initialize
$range_start = $code;
$range_end = $code;
$range_category = $category;
- if ($name =~ /<.*, First>$/) {
+ if ($name =~ /<.*, First>$/)
+ {
$gap_category = $category;
- } else {
+ }
+ else
+ {
$gap_category = $CATEGORY_UNASSIGNED;
}
next;
@@ -71,10 +96,17 @@ while (my $line = <$FH>)
# Gap in codepoints detected. If it's a different category than
# the current range, emit the current range and initialize a new
# range representing the gap.
- if ($range_end + 1 != $code && $range_category ne $gap_category) {
- if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+ if ($range_end + 1 != $code && $range_category ne $gap_category)
+ {
+ if ($range_category ne $CATEGORY_UNASSIGNED)
+ {
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
$range_start = $range_end + 1;
$range_end = $code - 1;
@@ -82,27 +114,39 @@ while (my $line = <$FH>)
}
# different category; new range
- if ($range_category ne $category) {
- if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+ if ($range_category ne $category)
+ {
+ if ($range_category ne $CATEGORY_UNASSIGNED)
+ {
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
$range_start = $code;
$range_end = $code;
$range_category = $category;
}
- if ($name =~ /<.*, First>$/) {
- die "<..., First> entry unexpectedly follows another <..., First> entry"
+ if ($name =~ /<.*, First>$/)
+ {
+ die
+ "<..., First> entry unexpectedly follows another <..., First> entry"
if $gap_category ne $CATEGORY_UNASSIGNED;
$gap_category = $category;
}
- elsif ($name =~ /<.*, Last>$/) {
- die "<..., First> and <..., Last> entries have mismatching general category"
+ elsif ($name =~ /<.*, Last>$/)
+ {
+ die
+ "<..., First> and <..., Last> entries have mismatching general category"
if $gap_category ne $category;
$gap_category = $CATEGORY_UNASSIGNED;
}
- else {
+ else
+ {
die "unexpected entry found between <..., First> and <..., Last>"
if $gap_category ne $CATEGORY_UNASSIGNED;
}
@@ -115,13 +159,17 @@ die "<..., First> entry with no corresponding <..., Last> entry"
if $gap_category ne $CATEGORY_UNASSIGNED;
# emit final range
-if ($range_category ne $CATEGORY_UNASSIGNED) {
- push(@category_ranges, {start => $range_start, end => $range_end,
- category => $range_category});
+if ($range_category ne $CATEGORY_UNASSIGNED)
+{
+ push(
+ @category_ranges,
+ {
+ start => $range_start,
+ end => $range_end,
+ category => $range_category
+ });
}
-my $num_ranges = scalar @category_ranges;
-
# See: https://www.unicode.org/reports/tr44/#General_Category_Values
my $categories = {
Cn => 'PG_U_UNASSIGNED',
@@ -156,11 +204,146 @@ my $categories = {
Pf => 'PG_U_FINAL_PUNCTUATION'
};
-# Start writing out the output files
+# Find White_Space and Hex_Digit characters
+my @white_space = ();
+my @hex_digits = ();
+my @join_control = ();
+open($FH, '<', "$output_path/PropList.txt")
+ or die "Could not open $output_path/PropList.txt: $!.";
+while (my $line = <$FH>)
+{
+ my $pattern = qr/([0-9A-F\.]+)\s*;\s*(\w+)\s*#.*/s;
+ next unless $line =~ $pattern;
+
+ my $code = $line =~ s/$pattern/$1/rg;
+ my $property = $line =~ s/$pattern/$2/rg;
+ my $start;
+ my $end;
+
+ if ($code =~ /\.\./)
+ {
+ # code range
+ my @sp = split /\.\./, $code;
+ $start = hex($sp[0]);
+ $end = hex($sp[1]);
+ }
+ else
+ {
+ # single code point
+ $start = hex($code);
+ $end = hex($code);
+ }
+
+ if ($property eq "White_Space")
+ {
+ push @white_space, { start => $start, end => $end };
+ for (my $i = $start; $i <= $end && $i < 0x80; $i++)
+ {
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_WHITE_SPACE";
+ }
+ }
+ elsif ($property eq "Hex_Digit")
+ {
+ push @hex_digits, { start => $start, end => $end };
+ for (my $i = $start; $i <= $end && $i < 0x80; $i++)
+ {
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_HEX_DIGIT";
+ }
+ }
+ elsif ($property eq "Join_Control")
+ {
+ push @join_control, { start => $start, end => $end };
+ for (my $i = $start; $i <= $end && $i < 0x80; $i++)
+ {
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_JOIN_CONTROL";
+ }
+ }
+}
+
+# Find Alphabetic, Lowercase, and Uppercase characters
+my @alphabetic = ();
+my @lowercase = ();
+my @uppercase = ();
+my @case_ignorable = ();
+open($FH, '<', "$output_path/DerivedCoreProperties.txt")
+ or die "Could not open $output_path/DerivedCoreProperties.txt: $!.";
+while (my $line = <$FH>)
+{
+ my $pattern = qr/^([0-9A-F\.]+)\s*;\s*(\w+)\s*#.*$/s;
+ next unless $line =~ $pattern;
+
+ my $code = $line =~ s/$pattern/$1/rg;
+ my $property = $line =~ s/$pattern/$2/rg;
+ my $start;
+ my $end;
+
+ if ($code =~ /\.\./)
+ {
+ # code range
+ my @sp = split /\.\./, $code;
+ die "line: {$line} code: {$code} sp[0] {$sp[0]} sp[1] {$sp[1]}"
+ unless $sp[0] =~ /^[0-9A-F]+$/ && $sp[1] =~ /^[0-9A-F]+$/;
+ $start = hex($sp[0]);
+ $end = hex($sp[1]);
+ }
+ else
+ {
+ die "line: {$line} code: {$code}" unless $code =~ /^[0-9A-F]+$/;
+ # single code point
+ $start = hex($code);
+ $end = hex($code);
+ }
+
+ if ($property eq "Alphabetic")
+ {
+ push @alphabetic, { start => $start, end => $end };
+ for (my $i = $start; $i <= $end && $i < 0x80; $i++)
+ {
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_ALPHABETIC";
+ }
+ }
+ elsif ($property eq "Lowercase")
+ {
+ push @lowercase, { start => $start, end => $end };
+ for (my $i = $start; $i <= $end && $i < 0x80; $i++)
+ {
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_LOWERCASE";
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_CASED";
+ }
+ }
+ elsif ($property eq "Uppercase")
+ {
+ push @uppercase, { start => $start, end => $end };
+ for (my $i = $start; $i <= $end && $i < 0x80; $i++)
+ {
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_UPPERCASE";
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_CASED";
+ }
+ }
+ elsif ($property eq "Case_Ignorable")
+ {
+ push @case_ignorable, { start => $start, end => $end };
+ for (my $i = $start; $i <= $end && $i < 0x80; $i++)
+ {
+ push @{ $opt_ascii{$i}{Properties} }, "PG_U_PROP_CASE_IGNORABLE";
+ }
+ }
+}
+
+my $num_category_ranges = scalar @category_ranges;
+my $num_alphabetic_ranges = scalar @alphabetic;
+my $num_lowercase_ranges = scalar @lowercase;
+my $num_uppercase_ranges = scalar @uppercase;
+my $num_case_ignorable_ranges = scalar @case_ignorable;
+my $num_white_space_ranges = scalar @white_space;
+my $num_hex_digit_ranges = scalar @hex_digits;
+my $num_join_control_ranges = scalar @join_control;
+
+# Start writing out the output file
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
-print $OT <<HEADER;
+print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
* unicode_category_table.h
@@ -188,18 +371,152 @@ typedef struct
uint8 category; /* General Category */
} pg_category_range;
-/* table of Unicode codepoint ranges and their categories */
-static const pg_category_range unicode_categories[$num_ranges] =
+typedef struct
+{
+ uint32 first; /* Unicode codepoint */
+ uint32 last; /* Unicode codepoint */
+} pg_unicode_range;
+
+typedef struct
+{
+ uint8 category;
+ uint8 properties;
+} pg_unicode_properties;
+
+/*
+ * The properties currently used, in no particular order. Fits in a uint8, but
+ * if more properties are added, a wider integer will be needed.
+ */
+#define PG_U_PROP_ALPHABETIC (1 << 0)
+#define PG_U_PROP_LOWERCASE (1 << 1)
+#define PG_U_PROP_UPPERCASE (1 << 2)
+#define PG_U_PROP_CASED (1 << 3)
+#define PG_U_PROP_CASE_IGNORABLE (1 << 4)
+#define PG_U_PROP_WHITE_SPACE (1 << 5)
+#define PG_U_PROP_JOIN_CONTROL (1 << 6)
+#define PG_U_PROP_HEX_DIGIT (1 << 7)
+
+EOS
+
+print $OT <<"EOS";
+/* table for fast lookup of ASCII codepoints */
+static const pg_unicode_properties unicode_opt_ascii[128] =
+{
+EOS
+
+for (my $i = 0; $i < 128; $i++)
{
-HEADER
+ my $category_string = $categories->{ $opt_ascii{$i}->{Category} };
+ my $props_str = (join ' | ', @{ $opt_ascii{$i}{Properties} }) || "0";
+ printf $OT
+ "\t{\n\t\t.category = $category_string,\n\t\t.properties = $props_str\n\t},\n";
+}
-my $firsttime = 1;
-foreach my $range (@category_ranges) {
- printf $OT ",\n" unless $firsttime;
- $firsttime = 0;
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges and their categories */
+static const pg_category_range unicode_categories[$num_category_ranges] =
+{
+EOS
- my $category = $categories->{$range->{category}};
+foreach my $range (@category_ranges)
+{
+ my $category = $categories->{ $range->{category} };
die "category missing: $range->{category}" unless $category;
- printf $OT "\t{0x%06x, 0x%06x, %s}", $range->{start}, $range->{end}, $category;
+ printf $OT "\t{0x%06x, 0x%06x, %s},\n", $range->{start}, $range->{end},
+ $category;
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Alphabetic characters */
+static const pg_unicode_range unicode_alphabetic[$num_alphabetic_ranges] =
+{
+EOS
+
+foreach my $range (@alphabetic)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Lowercase characters */
+static const pg_unicode_range unicode_lowercase[$num_lowercase_ranges] =
+{
+EOS
+
+foreach my $range (@lowercase)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Uppercase characters */
+static const pg_unicode_range unicode_uppercase[$num_uppercase_ranges] =
+{
+EOS
+
+foreach my $range (@uppercase)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
}
-print $OT "\n};\n";
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Case_Ignorable characters */
+static const pg_unicode_range unicode_case_ignorable[$num_case_ignorable_ranges] =
+{
+EOS
+
+foreach my $range (@case_ignorable)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of White_Space characters */
+static const pg_unicode_range unicode_white_space[$num_white_space_ranges] =
+{
+EOS
+
+foreach my $range (@white_space)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Hex_Digit characters */
+static const pg_unicode_range unicode_hex_digit[$num_hex_digit_ranges] =
+{
+EOS
+
+foreach my $range (@hex_digits)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n\n";
+
+print $OT <<"EOS";
+/* table of Unicode codepoint ranges of Join_Control characters */
+static const pg_unicode_range unicode_join_control[$num_join_control_ranges] =
+{
+EOS
+
+foreach my $range (@join_control)
+{
+ printf $OT "\t{0x%06x, 0x%06x},\n", $range->{start}, $range->{end};
+}
+
+print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index df4f3a4ed1..d7190bb8ca 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_category_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['UnicodeData.txt'], unicode_data['DerivedCoreProperties.txt'], unicode_data['PropList.txt']],
output: ['unicode_category_table.h'],
command: [
perl, files('generate-unicode_category_table.pl'),
diff --git a/src/common/unicode_category.c b/src/common/unicode_category.c
index 668051b461..bece7334f5 100644
--- a/src/common/unicode_category.c
+++ b/src/common/unicode_category.c
@@ -1,6 +1,8 @@
/*-------------------------------------------------------------------------
* unicode_category.c
- * Determine general category of Unicode characters.
+ * Determine general category and character properties of Unicode
+ * characters. Encoding must be UTF8, where we assume that the pg_wchar
+ * representation is a code point.
*
* Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
*
@@ -18,24 +20,85 @@
#include "common/unicode_category.h"
#include "common/unicode_category_table.h"
+/*
+ * Create bitmasks from pg_unicode_category values for efficient comparison of
+ * multiple categories. For instance, PG_U_MN_MASK is a bitmask representing
+ * the general cateogry Mn; and PG_U_M_MASK represents general categories Mn,
+ * Me, and Mc.
+ *
+ * The number of Unicode General Categories should never grow, so a 32-bit
+ * mask is fine.
+ */
+#define PG_U_CATEGORY_MASK(X) ((uint32)(1 << (X)))
+
+#define PG_U_LU_MASK PG_U_CATEGORY_MASK(PG_U_UPPERCASE_LETTER)
+#define PG_U_LL_MASK PG_U_CATEGORY_MASK(PG_U_LOWERCASE_LETTER)
+#define PG_U_LT_MASK PG_U_CATEGORY_MASK(PG_U_TITLECASE_LETTER)
+#define PG_U_LC_MASK (PG_U_LU_MASK|PG_U_LL_MASK|PG_U_LT_MASK)
+#define PG_U_LM_MASK PG_U_CATEGORY_MASK(PG_U_MODIFIER_LETTER)
+#define PG_U_LO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_LETTER)
+#define PG_U_L_MASK (PG_U_LU_MASK|PG_U_LL_MASK|PG_U_LT_MASK|PG_U_LM_MASK|\
+ PG_U_LO_MASK)
+#define PG_U_MN_MASK PG_U_CATEGORY_MASK(PG_U_NONSPACING_MARK)
+#define PG_U_ME_MASK PG_U_CATEGORY_MASK(PG_U_ENCLOSING_MARK)
+#define PG_U_MC_MASK PG_U_CATEGORY_MASK(PG_U_SPACING_MARK)
+#define PG_U_M_MASK (PG_U_MN_MASK|PG_U_MC_MASK|PG_U_ME_MASK)
+#define PG_U_ND_MASK PG_U_CATEGORY_MASK(PG_U_DECIMAL_NUMBER)
+#define PG_U_NL_MASK PG_U_CATEGORY_MASK(PG_U_LETTER_NUMBER)
+#define PG_U_NO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_NUMBER)
+#define PG_U_N_MASK (PG_U_ND_MASK|PG_U_NL_MASK|PG_U_NO_MASK)
+#define PG_U_PC_MASK PG_U_CATEGORY_MASK(PG_U_CONNECTOR_PUNCTUATION)
+#define PG_U_PD_MASK PG_U_CATEGORY_MASK(PG_U_DASH_PUNCTUATION)
+#define PG_U_PS_MASK PG_U_CATEGORY_MASK(PG_U_OPEN_PUNCTUATION)
+#define PG_U_PE_MASK PG_U_CATEGORY_MASK(PG_U_CLOSE_PUNCTUATION)
+#define PG_U_PI_MASK PG_U_CATEGORY_MASK(PG_U_INITIAL_PUNCTUATION)
+#define PG_U_PF_MASK PG_U_CATEGORY_MASK(PG_U_FINAL_PUNCTUATION)
+#define PG_U_PO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_PUNCTUATION)
+#define PG_U_P_MASK (PG_U_PC_MASK|PG_U_PD_MASK|PG_U_PS_MASK|PG_U_PE_MASK|\
+ PG_U_PI_MASK|PG_U_PF_MASK|PG_U_PO_MASK)
+#define PG_U_SM_MASK PG_U_CATEGORY_MASK(PG_U_MATH_SYMBOL)
+#define PG_U_SC_MASK PG_U_CATEGORY_MASK(PG_U_CURRENCY_SYMBOL)
+#define PG_U_SK_MASK PG_U_CATEGORY_MASK(PG_U_MODIFIER_SYMBOL)
+#define PG_U_SO_MASK PG_U_CATEGORY_MASK(PG_U_OTHER_SYMBOL)
+#define PG_U_S_MASK (PG_U_SM_MASK|PG_U_SC_MASK|PG_U_SK_MASK|PG_U_SO_MASK)
+#define PG_U_ZS_MASK PG_U_CATEGORY_MASK(PG_U_SPACE_SEPARATOR)
+#define PG_U_ZL_MASK PG_U_CATEGORY_MASK(PG_U_LINE_SEPARATOR)
+#define PG_U_ZP_MASK PG_U_CATEGORY_MASK(PG_U_PARAGRAPH_SEPARATOR)
+#define PG_U_Z_MASK (PG_U_ZS_MASK|PG_U_ZL_MASK|PG_U_ZP_MASK)
+#define PG_U_CC_MASK PG_U_CATEGORY_MASK(PG_U_CONTROL)
+#define PG_U_CF_MASK PG_U_CATEGORY_MASK(PG_U_FORMAT)
+#define PG_U_CS_MASK PG_U_CATEGORY_MASK(PG_U_SURROGATE)
+#define PG_U_CO_MASK PG_U_CATEGORY_MASK(PG_U_PRIVATE_USE)
+#define PG_U_CN_MASK PG_U_CATEGORY_MASK(PG_U_UNASSIGNED)
+#define PG_U_C_MASK (PG_U_CC_MASK|PG_U_CF_MASK|PG_U_CS_MASK|PG_U_CO_MASK|\
+ PG_U_CN_MASK)
+
+#define PG_U_CHARACTER_TAB 0x09
+
+static bool range_search(const pg_unicode_range * tbl, size_t size,
+ pg_wchar code);
+
/*
* Unicode general category for the given codepoint.
*/
pg_unicode_category
-unicode_category(pg_wchar ucs)
+unicode_category(pg_wchar code)
{
int min = 0;
int mid;
int max = lengthof(unicode_categories) - 1;
- Assert(ucs <= 0x10ffff);
+ Assert(code <= 0x10ffff);
+
+ if (code < 0x80)
+ return unicode_opt_ascii[code].category;
while (max >= min)
{
mid = (min + max) / 2;
- if (ucs > unicode_categories[mid].last)
+ if (code > unicode_categories[mid].last)
min = mid + 1;
- else if (ucs < unicode_categories[mid].first)
+ else if (code < unicode_categories[mid].first)
max = mid - 1;
else
return unicode_categories[mid].category;
@@ -44,6 +107,224 @@ unicode_category(pg_wchar ucs)
return PG_U_UNASSIGNED;
}
+bool
+pg_u_prop_alphabetic(pg_wchar code)
+{
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_ALPHABETIC;
+
+ return range_search(unicode_alphabetic,
+ lengthof(unicode_alphabetic),
+ code);
+}
+
+bool
+pg_u_prop_lowercase(pg_wchar code)
+{
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_LOWERCASE;
+
+ return range_search(unicode_lowercase,
+ lengthof(unicode_lowercase),
+ code);
+}
+
+bool
+pg_u_prop_uppercase(pg_wchar code)
+{
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_UPPERCASE;
+
+ return range_search(unicode_uppercase,
+ lengthof(unicode_uppercase),
+ code);
+}
+
+bool
+pg_u_prop_cased(pg_wchar code)
+{
+ uint32 category_mask;
+
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_CASED;
+
+ category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return category_mask & PG_U_LT_MASK ||
+ pg_u_prop_lowercase(code) ||
+ pg_u_prop_uppercase(code);
+}
+
+bool
+pg_u_prop_case_ignorable(pg_wchar code)
+{
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_CASE_IGNORABLE;
+
+ return range_search(unicode_case_ignorable,
+ lengthof(unicode_case_ignorable),
+ code);
+}
+
+bool
+pg_u_prop_white_space(pg_wchar code)
+{
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_WHITE_SPACE;
+
+ return range_search(unicode_white_space,
+ lengthof(unicode_white_space),
+ code);
+}
+
+bool
+pg_u_prop_hex_digit(pg_wchar code)
+{
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_HEX_DIGIT;
+
+ return range_search(unicode_hex_digit,
+ lengthof(unicode_hex_digit),
+ code);
+}
+
+bool
+pg_u_prop_join_control(pg_wchar code)
+{
+ if (code < 0x80)
+ return unicode_opt_ascii[code].properties & PG_U_PROP_JOIN_CONTROL;
+
+ return range_search(unicode_join_control,
+ lengthof(unicode_join_control),
+ code);
+}
+
+/*
+ * The following functions implement the Compatibility Properties described
+ * at: http://www.unicode.org/reports/tr18/#Compatibility_Properties
+ *
+ * If 'posix' is true, implements the "POSIX Compatible" variant, otherwise
+ * the "Standard" variant.
+ */
+
+bool
+pg_u_isdigit(pg_wchar code, bool posix)
+{
+ if (posix)
+ return ('0' <= code && code <= '9');
+ else
+ return unicode_category(code) == PG_U_DECIMAL_NUMBER;
+}
+
+bool
+pg_u_isalpha(pg_wchar code)
+{
+ return pg_u_prop_alphabetic(code);
+}
+
+bool
+pg_u_isalnum(pg_wchar code, bool posix)
+{
+ return pg_u_isalpha(code) || pg_u_isdigit(code, posix);
+}
+
+bool
+pg_u_isword(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return
+ category_mask & (PG_U_M_MASK | PG_U_ND_MASK | PG_U_PC_MASK) ||
+ pg_u_isalpha(code) ||
+ pg_u_prop_join_control(code);
+}
+
+bool
+pg_u_isupper(pg_wchar code)
+{
+ return pg_u_prop_uppercase(code);
+}
+
+bool
+pg_u_islower(pg_wchar code)
+{
+ return pg_u_prop_lowercase(code);
+}
+
+bool
+pg_u_isblank(pg_wchar code)
+{
+ return code == PG_U_CHARACTER_TAB ||
+ unicode_category(code) == PG_U_SPACE_SEPARATOR;
+}
+
+bool
+pg_u_iscntrl(pg_wchar code)
+{
+ return unicode_category(code) == PG_U_CONTROL;
+}
+
+bool
+pg_u_isgraph(pg_wchar code)
+{
+ uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ if (category_mask & (PG_U_CC_MASK | PG_U_CS_MASK | PG_U_CN_MASK) ||
+ pg_u_isspace(code))
+ return false;
+ return true;
+}
+
+bool
+pg_u_isprint(pg_wchar code)
+{
+ pg_unicode_category category = unicode_category(code);
+
+ if (category == PG_U_CONTROL)
+ return false;
+
+ return pg_u_isgraph(code) || pg_u_isblank(code);
+}
+
+bool
+pg_u_ispunct(pg_wchar code, bool posix)
+{
+ uint32 category_mask;
+
+ if (posix)
+ {
+ if (pg_u_isalpha(code))
+ return false;
+
+ category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+ return category_mask & (PG_U_P_MASK | PG_U_S_MASK);
+ }
+ else
+ {
+ category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
+
+ return category_mask & PG_U_P_MASK;
+ }
+}
+
+bool
+pg_u_isspace(pg_wchar code)
+{
+ return pg_u_prop_white_space(code);
+}
+
+bool
+pg_u_isxdigit(pg_wchar code, bool posix)
+{
+ if (posix)
+ return (('0' <= code && code <= '9') ||
+ ('A' <= code && code <= 'F') ||
+ ('a' <= code && code <= 'f'));
+ else
+ return unicode_category(code) == PG_U_DECIMAL_NUMBER ||
+ pg_u_prop_hex_digit(code);
+}
+
/*
* Description of Unicode general category.
*/
@@ -191,3 +472,30 @@ unicode_category_abbrev(pg_unicode_category category)
Assert(false);
return "??"; /* keep compiler quiet */
}
+
+/*
+ * Binary search to test if given codepoint exists in one of the ranges in the
+ * given table.
+ */
+static bool
+range_search(const pg_unicode_range * tbl, size_t size, pg_wchar code)
+{
+ int min = 0;
+ int mid;
+ int max = size - 1;
+
+ Assert(code <= 0x10ffff);
+
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (code > tbl[mid].last)
+ min = mid + 1;
+ else if (code < tbl[mid].first)
+ max = mid - 1;
+ else
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/include/common/unicode_category.h b/src/include/common/unicode_category.h
index 5bad280615..f185b58900 100644
--- a/src/include/common/unicode_category.h
+++ b/src/include/common/unicode_category.h
@@ -62,7 +62,30 @@ typedef enum pg_unicode_category
} pg_unicode_category;
extern pg_unicode_category unicode_category(pg_wchar ucs);
-const char *unicode_category_string(pg_unicode_category category);
-const char *unicode_category_abbrev(pg_unicode_category category);
+extern const char *unicode_category_string(pg_unicode_category category);
+extern const char *unicode_category_abbrev(pg_unicode_category category);
+
+extern bool pg_u_prop_alphabetic(pg_wchar c);
+extern bool pg_u_prop_lowercase(pg_wchar c);
+extern bool pg_u_prop_uppercase(pg_wchar c);
+extern bool pg_u_prop_cased(pg_wchar c);
+extern bool pg_u_prop_case_ignorable(pg_wchar c);
+extern bool pg_u_prop_white_space(pg_wchar c);
+extern bool pg_u_prop_hex_digit(pg_wchar c);
+extern bool pg_u_prop_join_control(pg_wchar c);
+
+extern bool pg_u_isdigit(pg_wchar c, bool posix);
+extern bool pg_u_isalpha(pg_wchar c);
+extern bool pg_u_isalnum(pg_wchar c, bool posix);
+extern bool pg_u_isword(pg_wchar c);
+extern bool pg_u_isupper(pg_wchar c);
+extern bool pg_u_islower(pg_wchar c);
+extern bool pg_u_isblank(pg_wchar c);
+extern bool pg_u_iscntrl(pg_wchar c);
+extern bool pg_u_isgraph(pg_wchar c);
+extern bool pg_u_isprint(pg_wchar c);
+extern bool pg_u_ispunct(pg_wchar c, bool posix);
+extern bool pg_u_isspace(pg_wchar c);
+extern bool pg_u_isxdigit(pg_wchar c, bool posix);
#endif /* UNICODE_CATEGORY_H */
diff --git a/src/include/common/unicode_category_table.h b/src/include/common/unicode_category_table.h
index d7ef996189..02e8bf0c4c 100644
--- a/src/include/common/unicode_category_table.h
+++ b/src/include/common/unicode_category_table.h
@@ -25,6 +25,548 @@ typedef struct
uint8 category; /* General Category */
} pg_category_range;
+typedef struct
+{
+ uint32 first; /* Unicode codepoint */
+ uint32 last; /* Unicode codepoint */
+} pg_unicode_range;
+
+typedef struct
+{
+ uint8 category;
+ uint8 properties;
+} pg_unicode_properties;
+
+/*
+ * The properties currently used, in no particular order. Fits in a uint8, but
+ * if more properties are added, a wider integer will be needed.
+ */
+#define PG_U_PROP_ALPHABETIC (1 << 0)
+#define PG_U_PROP_LOWERCASE (1 << 1)
+#define PG_U_PROP_UPPERCASE (1 << 2)
+#define PG_U_PROP_CASED (1 << 3)
+#define PG_U_PROP_CASE_IGNORABLE (1 << 4)
+#define PG_U_PROP_WHITE_SPACE (1 << 5)
+#define PG_U_PROP_JOIN_CONTROL (1 << 6)
+#define PG_U_PROP_HEX_DIGIT (1 << 7)
+
+/* table for fast lookup of ASCII codepoints */
+static const pg_unicode_properties unicode_opt_ascii[128] =
+{
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = PG_U_PROP_WHITE_SPACE
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = PG_U_PROP_WHITE_SPACE
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = PG_U_PROP_WHITE_SPACE
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = PG_U_PROP_WHITE_SPACE
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = PG_U_PROP_WHITE_SPACE
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_SPACE_SEPARATOR,
+ .properties = PG_U_PROP_WHITE_SPACE
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CURRENCY_SYMBOL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = PG_U_PROP_CASE_IGNORABLE
+ },
+ {
+ .category = PG_U_OPEN_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CLOSE_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MATH_SYMBOL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_DASH_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = PG_U_PROP_CASE_IGNORABLE
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_DECIMAL_NUMBER,
+ .properties = PG_U_PROP_HEX_DIGIT
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = PG_U_PROP_CASE_IGNORABLE
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MATH_SYMBOL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MATH_SYMBOL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MATH_SYMBOL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_UPPERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_UPPERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_OPEN_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_OTHER_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CLOSE_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MODIFIER_SYMBOL,
+ .properties = PG_U_PROP_CASE_IGNORABLE
+ },
+ {
+ .category = PG_U_CONNECTOR_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MODIFIER_SYMBOL,
+ .properties = PG_U_PROP_CASE_IGNORABLE
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_HEX_DIGIT | PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_LOWERCASE_LETTER,
+ .properties = PG_U_PROP_ALPHABETIC | PG_U_PROP_LOWERCASE | PG_U_PROP_CASED
+ },
+ {
+ .category = PG_U_OPEN_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MATH_SYMBOL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CLOSE_PUNCTUATION,
+ .properties = 0
+ },
+ {
+ .category = PG_U_MATH_SYMBOL,
+ .properties = 0
+ },
+ {
+ .category = PG_U_CONTROL,
+ .properties = 0
+ },
+};
+
/* table of Unicode codepoint ranges and their categories */
static const pg_category_range unicode_categories[3302] =
{
@@ -3329,5 +3871,3027 @@ static const pg_category_range unicode_categories[3302] =
{0x0e0020, 0x0e007f, PG_U_FORMAT},
{0x0e0100, 0x0e01ef, PG_U_NONSPACING_MARK},
{0x0f0000, 0x0ffffd, PG_U_PRIVATE_USE},
- {0x100000, 0x10fffd, PG_U_PRIVATE_USE}
+ {0x100000, 0x10fffd, PG_U_PRIVATE_USE},
+};
+
+/* table of Unicode codepoint ranges of Alphabetic characters */
+static const pg_unicode_range unicode_alphabetic[1141] =
+{
+ {0x000041, 0x00005a},
+ {0x000061, 0x00007a},
+ {0x0000aa, 0x0000aa},
+ {0x0000b5, 0x0000b5},
+ {0x0000ba, 0x0000ba},
+ {0x0000c0, 0x0000d6},
+ {0x0000d8, 0x0000f6},
+ {0x0000f8, 0x0001ba},
+ {0x0001bb, 0x0001bb},
+ {0x0001bc, 0x0001bf},
+ {0x0001c0, 0x0001c3},
+ {0x0001c4, 0x000293},
+ {0x000294, 0x000294},
+ {0x000295, 0x0002af},
+ {0x0002b0, 0x0002c1},
+ {0x0002c6, 0x0002d1},
+ {0x0002e0, 0x0002e4},
+ {0x0002ec, 0x0002ec},
+ {0x0002ee, 0x0002ee},
+ {0x000345, 0x000345},
+ {0x000370, 0x000373},
+ {0x000374, 0x000374},
+ {0x000376, 0x000377},
+ {0x00037a, 0x00037a},
+ {0x00037b, 0x00037d},
+ {0x00037f, 0x00037f},
+ {0x000386, 0x000386},
+ {0x000388, 0x00038a},
+ {0x00038c, 0x00038c},
+ {0x00038e, 0x0003a1},
+ {0x0003a3, 0x0003f5},
+ {0x0003f7, 0x000481},
+ {0x00048a, 0x00052f},
+ {0x000531, 0x000556},
+ {0x000559, 0x000559},
+ {0x000560, 0x000588},
+ {0x0005b0, 0x0005bd},
+ {0x0005bf, 0x0005bf},
+ {0x0005c1, 0x0005c2},
+ {0x0005c4, 0x0005c5},
+ {0x0005c7, 0x0005c7},
+ {0x0005d0, 0x0005ea},
+ {0x0005ef, 0x0005f2},
+ {0x000610, 0x00061a},
+ {0x000620, 0x00063f},
+ {0x000640, 0x000640},
+ {0x000641, 0x00064a},
+ {0x00064b, 0x000657},
+ {0x000659, 0x00065f},
+ {0x00066e, 0x00066f},
+ {0x000670, 0x000670},
+ {0x000671, 0x0006d3},
+ {0x0006d5, 0x0006d5},
+ {0x0006d6, 0x0006dc},
+ {0x0006e1, 0x0006e4},
+ {0x0006e5, 0x0006e6},
+ {0x0006e7, 0x0006e8},
+ {0x0006ed, 0x0006ed},
+ {0x0006ee, 0x0006ef},
+ {0x0006fa, 0x0006fc},
+ {0x0006ff, 0x0006ff},
+ {0x000710, 0x000710},
+ {0x000711, 0x000711},
+ {0x000712, 0x00072f},
+ {0x000730, 0x00073f},
+ {0x00074d, 0x0007a5},
+ {0x0007a6, 0x0007b0},
+ {0x0007b1, 0x0007b1},
+ {0x0007ca, 0x0007ea},
+ {0x0007f4, 0x0007f5},
+ {0x0007fa, 0x0007fa},
+ {0x000800, 0x000815},
+ {0x000816, 0x000817},
+ {0x00081a, 0x00081a},
+ {0x00081b, 0x000823},
+ {0x000824, 0x000824},
+ {0x000825, 0x000827},
+ {0x000828, 0x000828},
+ {0x000829, 0x00082c},
+ {0x000840, 0x000858},
+ {0x000860, 0x00086a},
+ {0x000870, 0x000887},
+ {0x000889, 0x00088e},
+ {0x0008a0, 0x0008c8},
+ {0x0008c9, 0x0008c9},
+ {0x0008d4, 0x0008df},
+ {0x0008e3, 0x0008e9},
+ {0x0008f0, 0x000902},
+ {0x000903, 0x000903},
+ {0x000904, 0x000939},
+ {0x00093a, 0x00093a},
+ {0x00093b, 0x00093b},
+ {0x00093d, 0x00093d},
+ {0x00093e, 0x000940},
+ {0x000941, 0x000948},
+ {0x000949, 0x00094c},
+ {0x00094e, 0x00094f},
+ {0x000950, 0x000950},
+ {0x000955, 0x000957},
+ {0x000958, 0x000961},
+ {0x000962, 0x000963},
+ {0x000971, 0x000971},
+ {0x000972, 0x000980},
+ {0x000981, 0x000981},
+ {0x000982, 0x000983},
+ {0x000985, 0x00098c},
+ {0x00098f, 0x000990},
+ {0x000993, 0x0009a8},
+ {0x0009aa, 0x0009b0},
+ {0x0009b2, 0x0009b2},
+ {0x0009b6, 0x0009b9},
+ {0x0009bd, 0x0009bd},
+ {0x0009be, 0x0009c0},
+ {0x0009c1, 0x0009c4},
+ {0x0009c7, 0x0009c8},
+ {0x0009cb, 0x0009cc},
+ {0x0009ce, 0x0009ce},
+ {0x0009d7, 0x0009d7},
+ {0x0009dc, 0x0009dd},
+ {0x0009df, 0x0009e1},
+ {0x0009e2, 0x0009e3},
+ {0x0009f0, 0x0009f1},
+ {0x0009fc, 0x0009fc},
+ {0x000a01, 0x000a02},
+ {0x000a03, 0x000a03},
+ {0x000a05, 0x000a0a},
+ {0x000a0f, 0x000a10},
+ {0x000a13, 0x000a28},
+ {0x000a2a, 0x000a30},
+ {0x000a32, 0x000a33},
+ {0x000a35, 0x000a36},
+ {0x000a38, 0x000a39},
+ {0x000a3e, 0x000a40},
+ {0x000a41, 0x000a42},
+ {0x000a47, 0x000a48},
+ {0x000a4b, 0x000a4c},
+ {0x000a51, 0x000a51},
+ {0x000a59, 0x000a5c},
+ {0x000a5e, 0x000a5e},
+ {0x000a70, 0x000a71},
+ {0x000a72, 0x000a74},
+ {0x000a75, 0x000a75},
+ {0x000a81, 0x000a82},
+ {0x000a83, 0x000a83},
+ {0x000a85, 0x000a8d},
+ {0x000a8f, 0x000a91},
+ {0x000a93, 0x000aa8},
+ {0x000aaa, 0x000ab0},
+ {0x000ab2, 0x000ab3},
+ {0x000ab5, 0x000ab9},
+ {0x000abd, 0x000abd},
+ {0x000abe, 0x000ac0},
+ {0x000ac1, 0x000ac5},
+ {0x000ac7, 0x000ac8},
+ {0x000ac9, 0x000ac9},
+ {0x000acb, 0x000acc},
+ {0x000ad0, 0x000ad0},
+ {0x000ae0, 0x000ae1},
+ {0x000ae2, 0x000ae3},
+ {0x000af9, 0x000af9},
+ {0x000afa, 0x000afc},
+ {0x000b01, 0x000b01},
+ {0x000b02, 0x000b03},
+ {0x000b05, 0x000b0c},
+ {0x000b0f, 0x000b10},
+ {0x000b13, 0x000b28},
+ {0x000b2a, 0x000b30},
+ {0x000b32, 0x000b33},
+ {0x000b35, 0x000b39},
+ {0x000b3d, 0x000b3d},
+ {0x000b3e, 0x000b3e},
+ {0x000b3f, 0x000b3f},
+ {0x000b40, 0x000b40},
+ {0x000b41, 0x000b44},
+ {0x000b47, 0x000b48},
+ {0x000b4b, 0x000b4c},
+ {0x000b56, 0x000b56},
+ {0x000b57, 0x000b57},
+ {0x000b5c, 0x000b5d},
+ {0x000b5f, 0x000b61},
+ {0x000b62, 0x000b63},
+ {0x000b71, 0x000b71},
+ {0x000b82, 0x000b82},
+ {0x000b83, 0x000b83},
+ {0x000b85, 0x000b8a},
+ {0x000b8e, 0x000b90},
+ {0x000b92, 0x000b95},
+ {0x000b99, 0x000b9a},
+ {0x000b9c, 0x000b9c},
+ {0x000b9e, 0x000b9f},
+ {0x000ba3, 0x000ba4},
+ {0x000ba8, 0x000baa},
+ {0x000bae, 0x000bb9},
+ {0x000bbe, 0x000bbf},
+ {0x000bc0, 0x000bc0},
+ {0x000bc1, 0x000bc2},
+ {0x000bc6, 0x000bc8},
+ {0x000bca, 0x000bcc},
+ {0x000bd0, 0x000bd0},
+ {0x000bd7, 0x000bd7},
+ {0x000c00, 0x000c00},
+ {0x000c01, 0x000c03},
+ {0x000c04, 0x000c04},
+ {0x000c05, 0x000c0c},
+ {0x000c0e, 0x000c10},
+ {0x000c12, 0x000c28},
+ {0x000c2a, 0x000c39},
+ {0x000c3d, 0x000c3d},
+ {0x000c3e, 0x000c40},
+ {0x000c41, 0x000c44},
+ {0x000c46, 0x000c48},
+ {0x000c4a, 0x000c4c},
+ {0x000c55, 0x000c56},
+ {0x000c58, 0x000c5a},
+ {0x000c5d, 0x000c5d},
+ {0x000c60, 0x000c61},
+ {0x000c62, 0x000c63},
+ {0x000c80, 0x000c80},
+ {0x000c81, 0x000c81},
+ {0x000c82, 0x000c83},
+ {0x000c85, 0x000c8c},
+ {0x000c8e, 0x000c90},
+ {0x000c92, 0x000ca8},
+ {0x000caa, 0x000cb3},
+ {0x000cb5, 0x000cb9},
+ {0x000cbd, 0x000cbd},
+ {0x000cbe, 0x000cbe},
+ {0x000cbf, 0x000cbf},
+ {0x000cc0, 0x000cc4},
+ {0x000cc6, 0x000cc6},
+ {0x000cc7, 0x000cc8},
+ {0x000cca, 0x000ccb},
+ {0x000ccc, 0x000ccc},
+ {0x000cd5, 0x000cd6},
+ {0x000cdd, 0x000cde},
+ {0x000ce0, 0x000ce1},
+ {0x000ce2, 0x000ce3},
+ {0x000cf1, 0x000cf2},
+ {0x000cf3, 0x000cf3},
+ {0x000d00, 0x000d01},
+ {0x000d02, 0x000d03},
+ {0x000d04, 0x000d0c},
+ {0x000d0e, 0x000d10},
+ {0x000d12, 0x000d3a},
+ {0x000d3d, 0x000d3d},
+ {0x000d3e, 0x000d40},
+ {0x000d41, 0x000d44},
+ {0x000d46, 0x000d48},
+ {0x000d4a, 0x000d4c},
+ {0x000d4e, 0x000d4e},
+ {0x000d54, 0x000d56},
+ {0x000d57, 0x000d57},
+ {0x000d5f, 0x000d61},
+ {0x000d62, 0x000d63},
+ {0x000d7a, 0x000d7f},
+ {0x000d81, 0x000d81},
+ {0x000d82, 0x000d83},
+ {0x000d85, 0x000d96},
+ {0x000d9a, 0x000db1},
+ {0x000db3, 0x000dbb},
+ {0x000dbd, 0x000dbd},
+ {0x000dc0, 0x000dc6},
+ {0x000dcf, 0x000dd1},
+ {0x000dd2, 0x000dd4},
+ {0x000dd6, 0x000dd6},
+ {0x000dd8, 0x000ddf},
+ {0x000df2, 0x000df3},
+ {0x000e01, 0x000e30},
+ {0x000e31, 0x000e31},
+ {0x000e32, 0x000e33},
+ {0x000e34, 0x000e3a},
+ {0x000e40, 0x000e45},
+ {0x000e46, 0x000e46},
+ {0x000e4d, 0x000e4d},
+ {0x000e81, 0x000e82},
+ {0x000e84, 0x000e84},
+ {0x000e86, 0x000e8a},
+ {0x000e8c, 0x000ea3},
+ {0x000ea5, 0x000ea5},
+ {0x000ea7, 0x000eb0},
+ {0x000eb1, 0x000eb1},
+ {0x000eb2, 0x000eb3},
+ {0x000eb4, 0x000eb9},
+ {0x000ebb, 0x000ebc},
+ {0x000ebd, 0x000ebd},
+ {0x000ec0, 0x000ec4},
+ {0x000ec6, 0x000ec6},
+ {0x000ecd, 0x000ecd},
+ {0x000edc, 0x000edf},
+ {0x000f00, 0x000f00},
+ {0x000f40, 0x000f47},
+ {0x000f49, 0x000f6c},
+ {0x000f71, 0x000f7e},
+ {0x000f7f, 0x000f7f},
+ {0x000f80, 0x000f83},
+ {0x000f88, 0x000f8c},
+ {0x000f8d, 0x000f97},
+ {0x000f99, 0x000fbc},
+ {0x001000, 0x00102a},
+ {0x00102b, 0x00102c},
+ {0x00102d, 0x001030},
+ {0x001031, 0x001031},
+ {0x001032, 0x001036},
+ {0x001038, 0x001038},
+ {0x00103b, 0x00103c},
+ {0x00103d, 0x00103e},
+ {0x00103f, 0x00103f},
+ {0x001050, 0x001055},
+ {0x001056, 0x001057},
+ {0x001058, 0x001059},
+ {0x00105a, 0x00105d},
+ {0x00105e, 0x001060},
+ {0x001061, 0x001061},
+ {0x001062, 0x001064},
+ {0x001065, 0x001066},
+ {0x001067, 0x00106d},
+ {0x00106e, 0x001070},
+ {0x001071, 0x001074},
+ {0x001075, 0x001081},
+ {0x001082, 0x001082},
+ {0x001083, 0x001084},
+ {0x001085, 0x001086},
+ {0x001087, 0x00108c},
+ {0x00108d, 0x00108d},
+ {0x00108e, 0x00108e},
+ {0x00108f, 0x00108f},
+ {0x00109a, 0x00109c},
+ {0x00109d, 0x00109d},
+ {0x0010a0, 0x0010c5},
+ {0x0010c7, 0x0010c7},
+ {0x0010cd, 0x0010cd},
+ {0x0010d0, 0x0010fa},
+ {0x0010fc, 0x0010fc},
+ {0x0010fd, 0x0010ff},
+ {0x001100, 0x001248},
+ {0x00124a, 0x00124d},
+ {0x001250, 0x001256},
+ {0x001258, 0x001258},
+ {0x00125a, 0x00125d},
+ {0x001260, 0x001288},
+ {0x00128a, 0x00128d},
+ {0x001290, 0x0012b0},
+ {0x0012b2, 0x0012b5},
+ {0x0012b8, 0x0012be},
+ {0x0012c0, 0x0012c0},
+ {0x0012c2, 0x0012c5},
+ {0x0012c8, 0x0012d6},
+ {0x0012d8, 0x001310},
+ {0x001312, 0x001315},
+ {0x001318, 0x00135a},
+ {0x001380, 0x00138f},
+ {0x0013a0, 0x0013f5},
+ {0x0013f8, 0x0013fd},
+ {0x001401, 0x00166c},
+ {0x00166f, 0x00167f},
+ {0x001681, 0x00169a},
+ {0x0016a0, 0x0016ea},
+ {0x0016ee, 0x0016f0},
+ {0x0016f1, 0x0016f8},
+ {0x001700, 0x001711},
+ {0x001712, 0x001713},
+ {0x00171f, 0x001731},
+ {0x001732, 0x001733},
+ {0x001740, 0x001751},
+ {0x001752, 0x001753},
+ {0x001760, 0x00176c},
+ {0x00176e, 0x001770},
+ {0x001772, 0x001773},
+ {0x001780, 0x0017b3},
+ {0x0017b6, 0x0017b6},
+ {0x0017b7, 0x0017bd},
+ {0x0017be, 0x0017c5},
+ {0x0017c6, 0x0017c6},
+ {0x0017c7, 0x0017c8},
+ {0x0017d7, 0x0017d7},
+ {0x0017dc, 0x0017dc},
+ {0x001820, 0x001842},
+ {0x001843, 0x001843},
+ {0x001844, 0x001878},
+ {0x001880, 0x001884},
+ {0x001885, 0x001886},
+ {0x001887, 0x0018a8},
+ {0x0018a9, 0x0018a9},
+ {0x0018aa, 0x0018aa},
+ {0x0018b0, 0x0018f5},
+ {0x001900, 0x00191e},
+ {0x001920, 0x001922},
+ {0x001923, 0x001926},
+ {0x001927, 0x001928},
+ {0x001929, 0x00192b},
+ {0x001930, 0x001931},
+ {0x001932, 0x001932},
+ {0x001933, 0x001938},
+ {0x001950, 0x00196d},
+ {0x001970, 0x001974},
+ {0x001980, 0x0019ab},
+ {0x0019b0, 0x0019c9},
+ {0x001a00, 0x001a16},
+ {0x001a17, 0x001a18},
+ {0x001a19, 0x001a1a},
+ {0x001a1b, 0x001a1b},
+ {0x001a20, 0x001a54},
+ {0x001a55, 0x001a55},
+ {0x001a56, 0x001a56},
+ {0x001a57, 0x001a57},
+ {0x001a58, 0x001a5e},
+ {0x001a61, 0x001a61},
+ {0x001a62, 0x001a62},
+ {0x001a63, 0x001a64},
+ {0x001a65, 0x001a6c},
+ {0x001a6d, 0x001a72},
+ {0x001a73, 0x001a74},
+ {0x001aa7, 0x001aa7},
+ {0x001abf, 0x001ac0},
+ {0x001acc, 0x001ace},
+ {0x001b00, 0x001b03},
+ {0x001b04, 0x001b04},
+ {0x001b05, 0x001b33},
+ {0x001b35, 0x001b35},
+ {0x001b36, 0x001b3a},
+ {0x001b3b, 0x001b3b},
+ {0x001b3c, 0x001b3c},
+ {0x001b3d, 0x001b41},
+ {0x001b42, 0x001b42},
+ {0x001b43, 0x001b43},
+ {0x001b45, 0x001b4c},
+ {0x001b80, 0x001b81},
+ {0x001b82, 0x001b82},
+ {0x001b83, 0x001ba0},
+ {0x001ba1, 0x001ba1},
+ {0x001ba2, 0x001ba5},
+ {0x001ba6, 0x001ba7},
+ {0x001ba8, 0x001ba9},
+ {0x001bac, 0x001bad},
+ {0x001bae, 0x001baf},
+ {0x001bba, 0x001be5},
+ {0x001be7, 0x001be7},
+ {0x001be8, 0x001be9},
+ {0x001bea, 0x001bec},
+ {0x001bed, 0x001bed},
+ {0x001bee, 0x001bee},
+ {0x001bef, 0x001bf1},
+ {0x001c00, 0x001c23},
+ {0x001c24, 0x001c2b},
+ {0x001c2c, 0x001c33},
+ {0x001c34, 0x001c35},
+ {0x001c36, 0x001c36},
+ {0x001c4d, 0x001c4f},
+ {0x001c5a, 0x001c77},
+ {0x001c78, 0x001c7d},
+ {0x001c80, 0x001c88},
+ {0x001c90, 0x001cba},
+ {0x001cbd, 0x001cbf},
+ {0x001ce9, 0x001cec},
+ {0x001cee, 0x001cf3},
+ {0x001cf5, 0x001cf6},
+ {0x001cfa, 0x001cfa},
+ {0x001d00, 0x001d2b},
+ {0x001d2c, 0x001d6a},
+ {0x001d6b, 0x001d77},
+ {0x001d78, 0x001d78},
+ {0x001d79, 0x001d9a},
+ {0x001d9b, 0x001dbf},
+ {0x001de7, 0x001df4},
+ {0x001e00, 0x001f15},
+ {0x001f18, 0x001f1d},
+ {0x001f20, 0x001f45},
+ {0x001f48, 0x001f4d},
+ {0x001f50, 0x001f57},
+ {0x001f59, 0x001f59},
+ {0x001f5b, 0x001f5b},
+ {0x001f5d, 0x001f5d},
+ {0x001f5f, 0x001f7d},
+ {0x001f80, 0x001fb4},
+ {0x001fb6, 0x001fbc},
+ {0x001fbe, 0x001fbe},
+ {0x001fc2, 0x001fc4},
+ {0x001fc6, 0x001fcc},
+ {0x001fd0, 0x001fd3},
+ {0x001fd6, 0x001fdb},
+ {0x001fe0, 0x001fec},
+ {0x001ff2, 0x001ff4},
+ {0x001ff6, 0x001ffc},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x002102, 0x002102},
+ {0x002107, 0x002107},
+ {0x00210a, 0x002113},
+ {0x002115, 0x002115},
+ {0x002119, 0x00211d},
+ {0x002124, 0x002124},
+ {0x002126, 0x002126},
+ {0x002128, 0x002128},
+ {0x00212a, 0x00212d},
+ {0x00212f, 0x002134},
+ {0x002135, 0x002138},
+ {0x002139, 0x002139},
+ {0x00213c, 0x00213f},
+ {0x002145, 0x002149},
+ {0x00214e, 0x00214e},
+ {0x002160, 0x002182},
+ {0x002183, 0x002184},
+ {0x002185, 0x002188},
+ {0x0024b6, 0x0024e9},
+ {0x002c00, 0x002c7b},
+ {0x002c7c, 0x002c7d},
+ {0x002c7e, 0x002ce4},
+ {0x002ceb, 0x002cee},
+ {0x002cf2, 0x002cf3},
+ {0x002d00, 0x002d25},
+ {0x002d27, 0x002d27},
+ {0x002d2d, 0x002d2d},
+ {0x002d30, 0x002d67},
+ {0x002d6f, 0x002d6f},
+ {0x002d80, 0x002d96},
+ {0x002da0, 0x002da6},
+ {0x002da8, 0x002dae},
+ {0x002db0, 0x002db6},
+ {0x002db8, 0x002dbe},
+ {0x002dc0, 0x002dc6},
+ {0x002dc8, 0x002dce},
+ {0x002dd0, 0x002dd6},
+ {0x002dd8, 0x002dde},
+ {0x002de0, 0x002dff},
+ {0x002e2f, 0x002e2f},
+ {0x003005, 0x003005},
+ {0x003006, 0x003006},
+ {0x003007, 0x003007},
+ {0x003021, 0x003029},
+ {0x003031, 0x003035},
+ {0x003038, 0x00303a},
+ {0x00303b, 0x00303b},
+ {0x00303c, 0x00303c},
+ {0x003041, 0x003096},
+ {0x00309d, 0x00309e},
+ {0x00309f, 0x00309f},
+ {0x0030a1, 0x0030fa},
+ {0x0030fc, 0x0030fe},
+ {0x0030ff, 0x0030ff},
+ {0x003105, 0x00312f},
+ {0x003131, 0x00318e},
+ {0x0031a0, 0x0031bf},
+ {0x0031f0, 0x0031ff},
+ {0x003400, 0x004dbf},
+ {0x004e00, 0x00a014},
+ {0x00a015, 0x00a015},
+ {0x00a016, 0x00a48c},
+ {0x00a4d0, 0x00a4f7},
+ {0x00a4f8, 0x00a4fd},
+ {0x00a500, 0x00a60b},
+ {0x00a60c, 0x00a60c},
+ {0x00a610, 0x00a61f},
+ {0x00a62a, 0x00a62b},
+ {0x00a640, 0x00a66d},
+ {0x00a66e, 0x00a66e},
+ {0x00a674, 0x00a67b},
+ {0x00a67f, 0x00a67f},
+ {0x00a680, 0x00a69b},
+ {0x00a69c, 0x00a69d},
+ {0x00a69e, 0x00a69f},
+ {0x00a6a0, 0x00a6e5},
+ {0x00a6e6, 0x00a6ef},
+ {0x00a717, 0x00a71f},
+ {0x00a722, 0x00a76f},
+ {0x00a770, 0x00a770},
+ {0x00a771, 0x00a787},
+ {0x00a788, 0x00a788},
+ {0x00a78b, 0x00a78e},
+ {0x00a78f, 0x00a78f},
+ {0x00a790, 0x00a7ca},
+ {0x00a7d0, 0x00a7d1},
+ {0x00a7d3, 0x00a7d3},
+ {0x00a7d5, 0x00a7d9},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f5, 0x00a7f6},
+ {0x00a7f7, 0x00a7f7},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a7fa, 0x00a7fa},
+ {0x00a7fb, 0x00a801},
+ {0x00a802, 0x00a802},
+ {0x00a803, 0x00a805},
+ {0x00a807, 0x00a80a},
+ {0x00a80b, 0x00a80b},
+ {0x00a80c, 0x00a822},
+ {0x00a823, 0x00a824},
+ {0x00a825, 0x00a826},
+ {0x00a827, 0x00a827},
+ {0x00a840, 0x00a873},
+ {0x00a880, 0x00a881},
+ {0x00a882, 0x00a8b3},
+ {0x00a8b4, 0x00a8c3},
+ {0x00a8c5, 0x00a8c5},
+ {0x00a8f2, 0x00a8f7},
+ {0x00a8fb, 0x00a8fb},
+ {0x00a8fd, 0x00a8fe},
+ {0x00a8ff, 0x00a8ff},
+ {0x00a90a, 0x00a925},
+ {0x00a926, 0x00a92a},
+ {0x00a930, 0x00a946},
+ {0x00a947, 0x00a951},
+ {0x00a952, 0x00a952},
+ {0x00a960, 0x00a97c},
+ {0x00a980, 0x00a982},
+ {0x00a983, 0x00a983},
+ {0x00a984, 0x00a9b2},
+ {0x00a9b4, 0x00a9b5},
+ {0x00a9b6, 0x00a9b9},
+ {0x00a9ba, 0x00a9bb},
+ {0x00a9bc, 0x00a9bd},
+ {0x00a9be, 0x00a9bf},
+ {0x00a9cf, 0x00a9cf},
+ {0x00a9e0, 0x00a9e4},
+ {0x00a9e5, 0x00a9e5},
+ {0x00a9e6, 0x00a9e6},
+ {0x00a9e7, 0x00a9ef},
+ {0x00a9fa, 0x00a9fe},
+ {0x00aa00, 0x00aa28},
+ {0x00aa29, 0x00aa2e},
+ {0x00aa2f, 0x00aa30},
+ {0x00aa31, 0x00aa32},
+ {0x00aa33, 0x00aa34},
+ {0x00aa35, 0x00aa36},
+ {0x00aa40, 0x00aa42},
+ {0x00aa43, 0x00aa43},
+ {0x00aa44, 0x00aa4b},
+ {0x00aa4c, 0x00aa4c},
+ {0x00aa4d, 0x00aa4d},
+ {0x00aa60, 0x00aa6f},
+ {0x00aa70, 0x00aa70},
+ {0x00aa71, 0x00aa76},
+ {0x00aa7a, 0x00aa7a},
+ {0x00aa7b, 0x00aa7b},
+ {0x00aa7c, 0x00aa7c},
+ {0x00aa7d, 0x00aa7d},
+ {0x00aa7e, 0x00aaaf},
+ {0x00aab0, 0x00aab0},
+ {0x00aab1, 0x00aab1},
+ {0x00aab2, 0x00aab4},
+ {0x00aab5, 0x00aab6},
+ {0x00aab7, 0x00aab8},
+ {0x00aab9, 0x00aabd},
+ {0x00aabe, 0x00aabe},
+ {0x00aac0, 0x00aac0},
+ {0x00aac2, 0x00aac2},
+ {0x00aadb, 0x00aadc},
+ {0x00aadd, 0x00aadd},
+ {0x00aae0, 0x00aaea},
+ {0x00aaeb, 0x00aaeb},
+ {0x00aaec, 0x00aaed},
+ {0x00aaee, 0x00aaef},
+ {0x00aaf2, 0x00aaf2},
+ {0x00aaf3, 0x00aaf4},
+ {0x00aaf5, 0x00aaf5},
+ {0x00ab01, 0x00ab06},
+ {0x00ab09, 0x00ab0e},
+ {0x00ab11, 0x00ab16},
+ {0x00ab20, 0x00ab26},
+ {0x00ab28, 0x00ab2e},
+ {0x00ab30, 0x00ab5a},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab60, 0x00ab68},
+ {0x00ab69, 0x00ab69},
+ {0x00ab70, 0x00abbf},
+ {0x00abc0, 0x00abe2},
+ {0x00abe3, 0x00abe4},
+ {0x00abe5, 0x00abe5},
+ {0x00abe6, 0x00abe7},
+ {0x00abe8, 0x00abe8},
+ {0x00abe9, 0x00abea},
+ {0x00ac00, 0x00d7a3},
+ {0x00d7b0, 0x00d7c6},
+ {0x00d7cb, 0x00d7fb},
+ {0x00f900, 0x00fa6d},
+ {0x00fa70, 0x00fad9},
+ {0x00fb00, 0x00fb06},
+ {0x00fb13, 0x00fb17},
+ {0x00fb1d, 0x00fb1d},
+ {0x00fb1e, 0x00fb1e},
+ {0x00fb1f, 0x00fb28},
+ {0x00fb2a, 0x00fb36},
+ {0x00fb38, 0x00fb3c},
+ {0x00fb3e, 0x00fb3e},
+ {0x00fb40, 0x00fb41},
+ {0x00fb43, 0x00fb44},
+ {0x00fb46, 0x00fbb1},
+ {0x00fbd3, 0x00fd3d},
+ {0x00fd50, 0x00fd8f},
+ {0x00fd92, 0x00fdc7},
+ {0x00fdf0, 0x00fdfb},
+ {0x00fe70, 0x00fe74},
+ {0x00fe76, 0x00fefc},
+ {0x00ff21, 0x00ff3a},
+ {0x00ff41, 0x00ff5a},
+ {0x00ff66, 0x00ff6f},
+ {0x00ff70, 0x00ff70},
+ {0x00ff71, 0x00ff9d},
+ {0x00ff9e, 0x00ff9f},
+ {0x00ffa0, 0x00ffbe},
+ {0x00ffc2, 0x00ffc7},
+ {0x00ffca, 0x00ffcf},
+ {0x00ffd2, 0x00ffd7},
+ {0x00ffda, 0x00ffdc},
+ {0x010000, 0x01000b},
+ {0x01000d, 0x010026},
+ {0x010028, 0x01003a},
+ {0x01003c, 0x01003d},
+ {0x01003f, 0x01004d},
+ {0x010050, 0x01005d},
+ {0x010080, 0x0100fa},
+ {0x010140, 0x010174},
+ {0x010280, 0x01029c},
+ {0x0102a0, 0x0102d0},
+ {0x010300, 0x01031f},
+ {0x01032d, 0x010340},
+ {0x010341, 0x010341},
+ {0x010342, 0x010349},
+ {0x01034a, 0x01034a},
+ {0x010350, 0x010375},
+ {0x010376, 0x01037a},
+ {0x010380, 0x01039d},
+ {0x0103a0, 0x0103c3},
+ {0x0103c8, 0x0103cf},
+ {0x0103d1, 0x0103d5},
+ {0x010400, 0x01044f},
+ {0x010450, 0x01049d},
+ {0x0104b0, 0x0104d3},
+ {0x0104d8, 0x0104fb},
+ {0x010500, 0x010527},
+ {0x010530, 0x010563},
+ {0x010570, 0x01057a},
+ {0x01057c, 0x01058a},
+ {0x01058c, 0x010592},
+ {0x010594, 0x010595},
+ {0x010597, 0x0105a1},
+ {0x0105a3, 0x0105b1},
+ {0x0105b3, 0x0105b9},
+ {0x0105bb, 0x0105bc},
+ {0x010600, 0x010736},
+ {0x010740, 0x010755},
+ {0x010760, 0x010767},
+ {0x010780, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010800, 0x010805},
+ {0x010808, 0x010808},
+ {0x01080a, 0x010835},
+ {0x010837, 0x010838},
+ {0x01083c, 0x01083c},
+ {0x01083f, 0x010855},
+ {0x010860, 0x010876},
+ {0x010880, 0x01089e},
+ {0x0108e0, 0x0108f2},
+ {0x0108f4, 0x0108f5},
+ {0x010900, 0x010915},
+ {0x010920, 0x010939},
+ {0x010980, 0x0109b7},
+ {0x0109be, 0x0109bf},
+ {0x010a00, 0x010a00},
+ {0x010a01, 0x010a03},
+ {0x010a05, 0x010a06},
+ {0x010a0c, 0x010a0f},
+ {0x010a10, 0x010a13},
+ {0x010a15, 0x010a17},
+ {0x010a19, 0x010a35},
+ {0x010a60, 0x010a7c},
+ {0x010a80, 0x010a9c},
+ {0x010ac0, 0x010ac7},
+ {0x010ac9, 0x010ae4},
+ {0x010b00, 0x010b35},
+ {0x010b40, 0x010b55},
+ {0x010b60, 0x010b72},
+ {0x010b80, 0x010b91},
+ {0x010c00, 0x010c48},
+ {0x010c80, 0x010cb2},
+ {0x010cc0, 0x010cf2},
+ {0x010d00, 0x010d23},
+ {0x010d24, 0x010d27},
+ {0x010e80, 0x010ea9},
+ {0x010eab, 0x010eac},
+ {0x010eb0, 0x010eb1},
+ {0x010f00, 0x010f1c},
+ {0x010f27, 0x010f27},
+ {0x010f30, 0x010f45},
+ {0x010f70, 0x010f81},
+ {0x010fb0, 0x010fc4},
+ {0x010fe0, 0x010ff6},
+ {0x011000, 0x011000},
+ {0x011001, 0x011001},
+ {0x011002, 0x011002},
+ {0x011003, 0x011037},
+ {0x011038, 0x011045},
+ {0x011071, 0x011072},
+ {0x011073, 0x011074},
+ {0x011075, 0x011075},
+ {0x011080, 0x011081},
+ {0x011082, 0x011082},
+ {0x011083, 0x0110af},
+ {0x0110b0, 0x0110b2},
+ {0x0110b3, 0x0110b6},
+ {0x0110b7, 0x0110b8},
+ {0x0110c2, 0x0110c2},
+ {0x0110d0, 0x0110e8},
+ {0x011100, 0x011102},
+ {0x011103, 0x011126},
+ {0x011127, 0x01112b},
+ {0x01112c, 0x01112c},
+ {0x01112d, 0x011132},
+ {0x011144, 0x011144},
+ {0x011145, 0x011146},
+ {0x011147, 0x011147},
+ {0x011150, 0x011172},
+ {0x011176, 0x011176},
+ {0x011180, 0x011181},
+ {0x011182, 0x011182},
+ {0x011183, 0x0111b2},
+ {0x0111b3, 0x0111b5},
+ {0x0111b6, 0x0111be},
+ {0x0111bf, 0x0111bf},
+ {0x0111c1, 0x0111c4},
+ {0x0111ce, 0x0111ce},
+ {0x0111cf, 0x0111cf},
+ {0x0111da, 0x0111da},
+ {0x0111dc, 0x0111dc},
+ {0x011200, 0x011211},
+ {0x011213, 0x01122b},
+ {0x01122c, 0x01122e},
+ {0x01122f, 0x011231},
+ {0x011232, 0x011233},
+ {0x011234, 0x011234},
+ {0x011237, 0x011237},
+ {0x01123e, 0x01123e},
+ {0x01123f, 0x011240},
+ {0x011241, 0x011241},
+ {0x011280, 0x011286},
+ {0x011288, 0x011288},
+ {0x01128a, 0x01128d},
+ {0x01128f, 0x01129d},
+ {0x01129f, 0x0112a8},
+ {0x0112b0, 0x0112de},
+ {0x0112df, 0x0112df},
+ {0x0112e0, 0x0112e2},
+ {0x0112e3, 0x0112e8},
+ {0x011300, 0x011301},
+ {0x011302, 0x011303},
+ {0x011305, 0x01130c},
+ {0x01130f, 0x011310},
+ {0x011313, 0x011328},
+ {0x01132a, 0x011330},
+ {0x011332, 0x011333},
+ {0x011335, 0x011339},
+ {0x01133d, 0x01133d},
+ {0x01133e, 0x01133f},
+ {0x011340, 0x011340},
+ {0x011341, 0x011344},
+ {0x011347, 0x011348},
+ {0x01134b, 0x01134c},
+ {0x011350, 0x011350},
+ {0x011357, 0x011357},
+ {0x01135d, 0x011361},
+ {0x011362, 0x011363},
+ {0x011400, 0x011434},
+ {0x011435, 0x011437},
+ {0x011438, 0x01143f},
+ {0x011440, 0x011441},
+ {0x011443, 0x011444},
+ {0x011445, 0x011445},
+ {0x011447, 0x01144a},
+ {0x01145f, 0x011461},
+ {0x011480, 0x0114af},
+ {0x0114b0, 0x0114b2},
+ {0x0114b3, 0x0114b8},
+ {0x0114b9, 0x0114b9},
+ {0x0114ba, 0x0114ba},
+ {0x0114bb, 0x0114be},
+ {0x0114bf, 0x0114c0},
+ {0x0114c1, 0x0114c1},
+ {0x0114c4, 0x0114c5},
+ {0x0114c7, 0x0114c7},
+ {0x011580, 0x0115ae},
+ {0x0115af, 0x0115b1},
+ {0x0115b2, 0x0115b5},
+ {0x0115b8, 0x0115bb},
+ {0x0115bc, 0x0115bd},
+ {0x0115be, 0x0115be},
+ {0x0115d8, 0x0115db},
+ {0x0115dc, 0x0115dd},
+ {0x011600, 0x01162f},
+ {0x011630, 0x011632},
+ {0x011633, 0x01163a},
+ {0x01163b, 0x01163c},
+ {0x01163d, 0x01163d},
+ {0x01163e, 0x01163e},
+ {0x011640, 0x011640},
+ {0x011644, 0x011644},
+ {0x011680, 0x0116aa},
+ {0x0116ab, 0x0116ab},
+ {0x0116ac, 0x0116ac},
+ {0x0116ad, 0x0116ad},
+ {0x0116ae, 0x0116af},
+ {0x0116b0, 0x0116b5},
+ {0x0116b8, 0x0116b8},
+ {0x011700, 0x01171a},
+ {0x01171d, 0x01171f},
+ {0x011720, 0x011721},
+ {0x011722, 0x011725},
+ {0x011726, 0x011726},
+ {0x011727, 0x01172a},
+ {0x011740, 0x011746},
+ {0x011800, 0x01182b},
+ {0x01182c, 0x01182e},
+ {0x01182f, 0x011837},
+ {0x011838, 0x011838},
+ {0x0118a0, 0x0118df},
+ {0x0118ff, 0x011906},
+ {0x011909, 0x011909},
+ {0x01190c, 0x011913},
+ {0x011915, 0x011916},
+ {0x011918, 0x01192f},
+ {0x011930, 0x011935},
+ {0x011937, 0x011938},
+ {0x01193b, 0x01193c},
+ {0x01193f, 0x01193f},
+ {0x011940, 0x011940},
+ {0x011941, 0x011941},
+ {0x011942, 0x011942},
+ {0x0119a0, 0x0119a7},
+ {0x0119aa, 0x0119d0},
+ {0x0119d1, 0x0119d3},
+ {0x0119d4, 0x0119d7},
+ {0x0119da, 0x0119db},
+ {0x0119dc, 0x0119df},
+ {0x0119e1, 0x0119e1},
+ {0x0119e3, 0x0119e3},
+ {0x0119e4, 0x0119e4},
+ {0x011a00, 0x011a00},
+ {0x011a01, 0x011a0a},
+ {0x011a0b, 0x011a32},
+ {0x011a35, 0x011a38},
+ {0x011a39, 0x011a39},
+ {0x011a3a, 0x011a3a},
+ {0x011a3b, 0x011a3e},
+ {0x011a50, 0x011a50},
+ {0x011a51, 0x011a56},
+ {0x011a57, 0x011a58},
+ {0x011a59, 0x011a5b},
+ {0x011a5c, 0x011a89},
+ {0x011a8a, 0x011a96},
+ {0x011a97, 0x011a97},
+ {0x011a9d, 0x011a9d},
+ {0x011ab0, 0x011af8},
+ {0x011c00, 0x011c08},
+ {0x011c0a, 0x011c2e},
+ {0x011c2f, 0x011c2f},
+ {0x011c30, 0x011c36},
+ {0x011c38, 0x011c3d},
+ {0x011c3e, 0x011c3e},
+ {0x011c40, 0x011c40},
+ {0x011c72, 0x011c8f},
+ {0x011c92, 0x011ca7},
+ {0x011ca9, 0x011ca9},
+ {0x011caa, 0x011cb0},
+ {0x011cb1, 0x011cb1},
+ {0x011cb2, 0x011cb3},
+ {0x011cb4, 0x011cb4},
+ {0x011cb5, 0x011cb6},
+ {0x011d00, 0x011d06},
+ {0x011d08, 0x011d09},
+ {0x011d0b, 0x011d30},
+ {0x011d31, 0x011d36},
+ {0x011d3a, 0x011d3a},
+ {0x011d3c, 0x011d3d},
+ {0x011d3f, 0x011d41},
+ {0x011d43, 0x011d43},
+ {0x011d46, 0x011d46},
+ {0x011d47, 0x011d47},
+ {0x011d60, 0x011d65},
+ {0x011d67, 0x011d68},
+ {0x011d6a, 0x011d89},
+ {0x011d8a, 0x011d8e},
+ {0x011d90, 0x011d91},
+ {0x011d93, 0x011d94},
+ {0x011d95, 0x011d95},
+ {0x011d96, 0x011d96},
+ {0x011d98, 0x011d98},
+ {0x011ee0, 0x011ef2},
+ {0x011ef3, 0x011ef4},
+ {0x011ef5, 0x011ef6},
+ {0x011f00, 0x011f01},
+ {0x011f02, 0x011f02},
+ {0x011f03, 0x011f03},
+ {0x011f04, 0x011f10},
+ {0x011f12, 0x011f33},
+ {0x011f34, 0x011f35},
+ {0x011f36, 0x011f3a},
+ {0x011f3e, 0x011f3f},
+ {0x011f40, 0x011f40},
+ {0x011fb0, 0x011fb0},
+ {0x012000, 0x012399},
+ {0x012400, 0x01246e},
+ {0x012480, 0x012543},
+ {0x012f90, 0x012ff0},
+ {0x013000, 0x01342f},
+ {0x013441, 0x013446},
+ {0x014400, 0x014646},
+ {0x016800, 0x016a38},
+ {0x016a40, 0x016a5e},
+ {0x016a70, 0x016abe},
+ {0x016ad0, 0x016aed},
+ {0x016b00, 0x016b2f},
+ {0x016b40, 0x016b43},
+ {0x016b63, 0x016b77},
+ {0x016b7d, 0x016b8f},
+ {0x016e40, 0x016e7f},
+ {0x016f00, 0x016f4a},
+ {0x016f4f, 0x016f4f},
+ {0x016f50, 0x016f50},
+ {0x016f51, 0x016f87},
+ {0x016f8f, 0x016f92},
+ {0x016f93, 0x016f9f},
+ {0x016fe0, 0x016fe1},
+ {0x016fe3, 0x016fe3},
+ {0x016ff0, 0x016ff1},
+ {0x017000, 0x0187f7},
+ {0x018800, 0x018cd5},
+ {0x018d00, 0x018d08},
+ {0x01aff0, 0x01aff3},
+ {0x01aff5, 0x01affb},
+ {0x01affd, 0x01affe},
+ {0x01b000, 0x01b122},
+ {0x01b132, 0x01b132},
+ {0x01b150, 0x01b152},
+ {0x01b155, 0x01b155},
+ {0x01b164, 0x01b167},
+ {0x01b170, 0x01b2fb},
+ {0x01bc00, 0x01bc6a},
+ {0x01bc70, 0x01bc7c},
+ {0x01bc80, 0x01bc88},
+ {0x01bc90, 0x01bc99},
+ {0x01bc9e, 0x01bc9e},
+ {0x01d400, 0x01d454},
+ {0x01d456, 0x01d49c},
+ {0x01d49e, 0x01d49f},
+ {0x01d4a2, 0x01d4a2},
+ {0x01d4a5, 0x01d4a6},
+ {0x01d4a9, 0x01d4ac},
+ {0x01d4ae, 0x01d4b9},
+ {0x01d4bb, 0x01d4bb},
+ {0x01d4bd, 0x01d4c3},
+ {0x01d4c5, 0x01d505},
+ {0x01d507, 0x01d50a},
+ {0x01d50d, 0x01d514},
+ {0x01d516, 0x01d51c},
+ {0x01d51e, 0x01d539},
+ {0x01d53b, 0x01d53e},
+ {0x01d540, 0x01d544},
+ {0x01d546, 0x01d546},
+ {0x01d54a, 0x01d550},
+ {0x01d552, 0x01d6a5},
+ {0x01d6a8, 0x01d6c0},
+ {0x01d6c2, 0x01d6da},
+ {0x01d6dc, 0x01d6fa},
+ {0x01d6fc, 0x01d714},
+ {0x01d716, 0x01d734},
+ {0x01d736, 0x01d74e},
+ {0x01d750, 0x01d76e},
+ {0x01d770, 0x01d788},
+ {0x01d78a, 0x01d7a8},
+ {0x01d7aa, 0x01d7c2},
+ {0x01d7c4, 0x01d7cb},
+ {0x01df00, 0x01df09},
+ {0x01df0a, 0x01df0a},
+ {0x01df0b, 0x01df1e},
+ {0x01df25, 0x01df2a},
+ {0x01e000, 0x01e006},
+ {0x01e008, 0x01e018},
+ {0x01e01b, 0x01e021},
+ {0x01e023, 0x01e024},
+ {0x01e026, 0x01e02a},
+ {0x01e030, 0x01e06d},
+ {0x01e08f, 0x01e08f},
+ {0x01e100, 0x01e12c},
+ {0x01e137, 0x01e13d},
+ {0x01e14e, 0x01e14e},
+ {0x01e290, 0x01e2ad},
+ {0x01e2c0, 0x01e2eb},
+ {0x01e4d0, 0x01e4ea},
+ {0x01e4eb, 0x01e4eb},
+ {0x01e7e0, 0x01e7e6},
+ {0x01e7e8, 0x01e7eb},
+ {0x01e7ed, 0x01e7ee},
+ {0x01e7f0, 0x01e7fe},
+ {0x01e800, 0x01e8c4},
+ {0x01e900, 0x01e943},
+ {0x01e947, 0x01e947},
+ {0x01e94b, 0x01e94b},
+ {0x01ee00, 0x01ee03},
+ {0x01ee05, 0x01ee1f},
+ {0x01ee21, 0x01ee22},
+ {0x01ee24, 0x01ee24},
+ {0x01ee27, 0x01ee27},
+ {0x01ee29, 0x01ee32},
+ {0x01ee34, 0x01ee37},
+ {0x01ee39, 0x01ee39},
+ {0x01ee3b, 0x01ee3b},
+ {0x01ee42, 0x01ee42},
+ {0x01ee47, 0x01ee47},
+ {0x01ee49, 0x01ee49},
+ {0x01ee4b, 0x01ee4b},
+ {0x01ee4d, 0x01ee4f},
+ {0x01ee51, 0x01ee52},
+ {0x01ee54, 0x01ee54},
+ {0x01ee57, 0x01ee57},
+ {0x01ee59, 0x01ee59},
+ {0x01ee5b, 0x01ee5b},
+ {0x01ee5d, 0x01ee5d},
+ {0x01ee5f, 0x01ee5f},
+ {0x01ee61, 0x01ee62},
+ {0x01ee64, 0x01ee64},
+ {0x01ee67, 0x01ee6a},
+ {0x01ee6c, 0x01ee72},
+ {0x01ee74, 0x01ee77},
+ {0x01ee79, 0x01ee7c},
+ {0x01ee7e, 0x01ee7e},
+ {0x01ee80, 0x01ee89},
+ {0x01ee8b, 0x01ee9b},
+ {0x01eea1, 0x01eea3},
+ {0x01eea5, 0x01eea9},
+ {0x01eeab, 0x01eebb},
+ {0x01f130, 0x01f149},
+ {0x01f150, 0x01f169},
+ {0x01f170, 0x01f189},
+ {0x020000, 0x02a6df},
+ {0x02a700, 0x02b739},
+ {0x02b740, 0x02b81d},
+ {0x02b820, 0x02cea1},
+ {0x02ceb0, 0x02ebe0},
+ {0x02ebf0, 0x02ee5d},
+ {0x02f800, 0x02fa1d},
+ {0x030000, 0x03134a},
+ {0x031350, 0x0323af},
+};
+
+/* table of Unicode codepoint ranges of Lowercase characters */
+static const pg_unicode_range unicode_lowercase[686] =
+{
+ {0x000061, 0x00007a},
+ {0x0000aa, 0x0000aa},
+ {0x0000b5, 0x0000b5},
+ {0x0000ba, 0x0000ba},
+ {0x0000df, 0x0000f6},
+ {0x0000f8, 0x0000ff},
+ {0x000101, 0x000101},
+ {0x000103, 0x000103},
+ {0x000105, 0x000105},
+ {0x000107, 0x000107},
+ {0x000109, 0x000109},
+ {0x00010b, 0x00010b},
+ {0x00010d, 0x00010d},
+ {0x00010f, 0x00010f},
+ {0x000111, 0x000111},
+ {0x000113, 0x000113},
+ {0x000115, 0x000115},
+ {0x000117, 0x000117},
+ {0x000119, 0x000119},
+ {0x00011b, 0x00011b},
+ {0x00011d, 0x00011d},
+ {0x00011f, 0x00011f},
+ {0x000121, 0x000121},
+ {0x000123, 0x000123},
+ {0x000125, 0x000125},
+ {0x000127, 0x000127},
+ {0x000129, 0x000129},
+ {0x00012b, 0x00012b},
+ {0x00012d, 0x00012d},
+ {0x00012f, 0x00012f},
+ {0x000131, 0x000131},
+ {0x000133, 0x000133},
+ {0x000135, 0x000135},
+ {0x000137, 0x000138},
+ {0x00013a, 0x00013a},
+ {0x00013c, 0x00013c},
+ {0x00013e, 0x00013e},
+ {0x000140, 0x000140},
+ {0x000142, 0x000142},
+ {0x000144, 0x000144},
+ {0x000146, 0x000146},
+ {0x000148, 0x000149},
+ {0x00014b, 0x00014b},
+ {0x00014d, 0x00014d},
+ {0x00014f, 0x00014f},
+ {0x000151, 0x000151},
+ {0x000153, 0x000153},
+ {0x000155, 0x000155},
+ {0x000157, 0x000157},
+ {0x000159, 0x000159},
+ {0x00015b, 0x00015b},
+ {0x00015d, 0x00015d},
+ {0x00015f, 0x00015f},
+ {0x000161, 0x000161},
+ {0x000163, 0x000163},
+ {0x000165, 0x000165},
+ {0x000167, 0x000167},
+ {0x000169, 0x000169},
+ {0x00016b, 0x00016b},
+ {0x00016d, 0x00016d},
+ {0x00016f, 0x00016f},
+ {0x000171, 0x000171},
+ {0x000173, 0x000173},
+ {0x000175, 0x000175},
+ {0x000177, 0x000177},
+ {0x00017a, 0x00017a},
+ {0x00017c, 0x00017c},
+ {0x00017e, 0x000180},
+ {0x000183, 0x000183},
+ {0x000185, 0x000185},
+ {0x000188, 0x000188},
+ {0x00018c, 0x00018d},
+ {0x000192, 0x000192},
+ {0x000195, 0x000195},
+ {0x000199, 0x00019b},
+ {0x00019e, 0x00019e},
+ {0x0001a1, 0x0001a1},
+ {0x0001a3, 0x0001a3},
+ {0x0001a5, 0x0001a5},
+ {0x0001a8, 0x0001a8},
+ {0x0001aa, 0x0001ab},
+ {0x0001ad, 0x0001ad},
+ {0x0001b0, 0x0001b0},
+ {0x0001b4, 0x0001b4},
+ {0x0001b6, 0x0001b6},
+ {0x0001b9, 0x0001ba},
+ {0x0001bd, 0x0001bf},
+ {0x0001c6, 0x0001c6},
+ {0x0001c9, 0x0001c9},
+ {0x0001cc, 0x0001cc},
+ {0x0001ce, 0x0001ce},
+ {0x0001d0, 0x0001d0},
+ {0x0001d2, 0x0001d2},
+ {0x0001d4, 0x0001d4},
+ {0x0001d6, 0x0001d6},
+ {0x0001d8, 0x0001d8},
+ {0x0001da, 0x0001da},
+ {0x0001dc, 0x0001dd},
+ {0x0001df, 0x0001df},
+ {0x0001e1, 0x0001e1},
+ {0x0001e3, 0x0001e3},
+ {0x0001e5, 0x0001e5},
+ {0x0001e7, 0x0001e7},
+ {0x0001e9, 0x0001e9},
+ {0x0001eb, 0x0001eb},
+ {0x0001ed, 0x0001ed},
+ {0x0001ef, 0x0001f0},
+ {0x0001f3, 0x0001f3},
+ {0x0001f5, 0x0001f5},
+ {0x0001f9, 0x0001f9},
+ {0x0001fb, 0x0001fb},
+ {0x0001fd, 0x0001fd},
+ {0x0001ff, 0x0001ff},
+ {0x000201, 0x000201},
+ {0x000203, 0x000203},
+ {0x000205, 0x000205},
+ {0x000207, 0x000207},
+ {0x000209, 0x000209},
+ {0x00020b, 0x00020b},
+ {0x00020d, 0x00020d},
+ {0x00020f, 0x00020f},
+ {0x000211, 0x000211},
+ {0x000213, 0x000213},
+ {0x000215, 0x000215},
+ {0x000217, 0x000217},
+ {0x000219, 0x000219},
+ {0x00021b, 0x00021b},
+ {0x00021d, 0x00021d},
+ {0x00021f, 0x00021f},
+ {0x000221, 0x000221},
+ {0x000223, 0x000223},
+ {0x000225, 0x000225},
+ {0x000227, 0x000227},
+ {0x000229, 0x000229},
+ {0x00022b, 0x00022b},
+ {0x00022d, 0x00022d},
+ {0x00022f, 0x00022f},
+ {0x000231, 0x000231},
+ {0x000233, 0x000239},
+ {0x00023c, 0x00023c},
+ {0x00023f, 0x000240},
+ {0x000242, 0x000242},
+ {0x000247, 0x000247},
+ {0x000249, 0x000249},
+ {0x00024b, 0x00024b},
+ {0x00024d, 0x00024d},
+ {0x00024f, 0x000293},
+ {0x000295, 0x0002af},
+ {0x0002b0, 0x0002b8},
+ {0x0002c0, 0x0002c1},
+ {0x0002e0, 0x0002e4},
+ {0x000345, 0x000345},
+ {0x000371, 0x000371},
+ {0x000373, 0x000373},
+ {0x000377, 0x000377},
+ {0x00037a, 0x00037a},
+ {0x00037b, 0x00037d},
+ {0x000390, 0x000390},
+ {0x0003ac, 0x0003ce},
+ {0x0003d0, 0x0003d1},
+ {0x0003d5, 0x0003d7},
+ {0x0003d9, 0x0003d9},
+ {0x0003db, 0x0003db},
+ {0x0003dd, 0x0003dd},
+ {0x0003df, 0x0003df},
+ {0x0003e1, 0x0003e1},
+ {0x0003e3, 0x0003e3},
+ {0x0003e5, 0x0003e5},
+ {0x0003e7, 0x0003e7},
+ {0x0003e9, 0x0003e9},
+ {0x0003eb, 0x0003eb},
+ {0x0003ed, 0x0003ed},
+ {0x0003ef, 0x0003f3},
+ {0x0003f5, 0x0003f5},
+ {0x0003f8, 0x0003f8},
+ {0x0003fb, 0x0003fc},
+ {0x000430, 0x00045f},
+ {0x000461, 0x000461},
+ {0x000463, 0x000463},
+ {0x000465, 0x000465},
+ {0x000467, 0x000467},
+ {0x000469, 0x000469},
+ {0x00046b, 0x00046b},
+ {0x00046d, 0x00046d},
+ {0x00046f, 0x00046f},
+ {0x000471, 0x000471},
+ {0x000473, 0x000473},
+ {0x000475, 0x000475},
+ {0x000477, 0x000477},
+ {0x000479, 0x000479},
+ {0x00047b, 0x00047b},
+ {0x00047d, 0x00047d},
+ {0x00047f, 0x00047f},
+ {0x000481, 0x000481},
+ {0x00048b, 0x00048b},
+ {0x00048d, 0x00048d},
+ {0x00048f, 0x00048f},
+ {0x000491, 0x000491},
+ {0x000493, 0x000493},
+ {0x000495, 0x000495},
+ {0x000497, 0x000497},
+ {0x000499, 0x000499},
+ {0x00049b, 0x00049b},
+ {0x00049d, 0x00049d},
+ {0x00049f, 0x00049f},
+ {0x0004a1, 0x0004a1},
+ {0x0004a3, 0x0004a3},
+ {0x0004a5, 0x0004a5},
+ {0x0004a7, 0x0004a7},
+ {0x0004a9, 0x0004a9},
+ {0x0004ab, 0x0004ab},
+ {0x0004ad, 0x0004ad},
+ {0x0004af, 0x0004af},
+ {0x0004b1, 0x0004b1},
+ {0x0004b3, 0x0004b3},
+ {0x0004b5, 0x0004b5},
+ {0x0004b7, 0x0004b7},
+ {0x0004b9, 0x0004b9},
+ {0x0004bb, 0x0004bb},
+ {0x0004bd, 0x0004bd},
+ {0x0004bf, 0x0004bf},
+ {0x0004c2, 0x0004c2},
+ {0x0004c4, 0x0004c4},
+ {0x0004c6, 0x0004c6},
+ {0x0004c8, 0x0004c8},
+ {0x0004ca, 0x0004ca},
+ {0x0004cc, 0x0004cc},
+ {0x0004ce, 0x0004cf},
+ {0x0004d1, 0x0004d1},
+ {0x0004d3, 0x0004d3},
+ {0x0004d5, 0x0004d5},
+ {0x0004d7, 0x0004d7},
+ {0x0004d9, 0x0004d9},
+ {0x0004db, 0x0004db},
+ {0x0004dd, 0x0004dd},
+ {0x0004df, 0x0004df},
+ {0x0004e1, 0x0004e1},
+ {0x0004e3, 0x0004e3},
+ {0x0004e5, 0x0004e5},
+ {0x0004e7, 0x0004e7},
+ {0x0004e9, 0x0004e9},
+ {0x0004eb, 0x0004eb},
+ {0x0004ed, 0x0004ed},
+ {0x0004ef, 0x0004ef},
+ {0x0004f1, 0x0004f1},
+ {0x0004f3, 0x0004f3},
+ {0x0004f5, 0x0004f5},
+ {0x0004f7, 0x0004f7},
+ {0x0004f9, 0x0004f9},
+ {0x0004fb, 0x0004fb},
+ {0x0004fd, 0x0004fd},
+ {0x0004ff, 0x0004ff},
+ {0x000501, 0x000501},
+ {0x000503, 0x000503},
+ {0x000505, 0x000505},
+ {0x000507, 0x000507},
+ {0x000509, 0x000509},
+ {0x00050b, 0x00050b},
+ {0x00050d, 0x00050d},
+ {0x00050f, 0x00050f},
+ {0x000511, 0x000511},
+ {0x000513, 0x000513},
+ {0x000515, 0x000515},
+ {0x000517, 0x000517},
+ {0x000519, 0x000519},
+ {0x00051b, 0x00051b},
+ {0x00051d, 0x00051d},
+ {0x00051f, 0x00051f},
+ {0x000521, 0x000521},
+ {0x000523, 0x000523},
+ {0x000525, 0x000525},
+ {0x000527, 0x000527},
+ {0x000529, 0x000529},
+ {0x00052b, 0x00052b},
+ {0x00052d, 0x00052d},
+ {0x00052f, 0x00052f},
+ {0x000560, 0x000588},
+ {0x0010d0, 0x0010fa},
+ {0x0010fc, 0x0010fc},
+ {0x0010fd, 0x0010ff},
+ {0x0013f8, 0x0013fd},
+ {0x001c80, 0x001c88},
+ {0x001d00, 0x001d2b},
+ {0x001d2c, 0x001d6a},
+ {0x001d6b, 0x001d77},
+ {0x001d78, 0x001d78},
+ {0x001d79, 0x001d9a},
+ {0x001d9b, 0x001dbf},
+ {0x001e01, 0x001e01},
+ {0x001e03, 0x001e03},
+ {0x001e05, 0x001e05},
+ {0x001e07, 0x001e07},
+ {0x001e09, 0x001e09},
+ {0x001e0b, 0x001e0b},
+ {0x001e0d, 0x001e0d},
+ {0x001e0f, 0x001e0f},
+ {0x001e11, 0x001e11},
+ {0x001e13, 0x001e13},
+ {0x001e15, 0x001e15},
+ {0x001e17, 0x001e17},
+ {0x001e19, 0x001e19},
+ {0x001e1b, 0x001e1b},
+ {0x001e1d, 0x001e1d},
+ {0x001e1f, 0x001e1f},
+ {0x001e21, 0x001e21},
+ {0x001e23, 0x001e23},
+ {0x001e25, 0x001e25},
+ {0x001e27, 0x001e27},
+ {0x001e29, 0x001e29},
+ {0x001e2b, 0x001e2b},
+ {0x001e2d, 0x001e2d},
+ {0x001e2f, 0x001e2f},
+ {0x001e31, 0x001e31},
+ {0x001e33, 0x001e33},
+ {0x001e35, 0x001e35},
+ {0x001e37, 0x001e37},
+ {0x001e39, 0x001e39},
+ {0x001e3b, 0x001e3b},
+ {0x001e3d, 0x001e3d},
+ {0x001e3f, 0x001e3f},
+ {0x001e41, 0x001e41},
+ {0x001e43, 0x001e43},
+ {0x001e45, 0x001e45},
+ {0x001e47, 0x001e47},
+ {0x001e49, 0x001e49},
+ {0x001e4b, 0x001e4b},
+ {0x001e4d, 0x001e4d},
+ {0x001e4f, 0x001e4f},
+ {0x001e51, 0x001e51},
+ {0x001e53, 0x001e53},
+ {0x001e55, 0x001e55},
+ {0x001e57, 0x001e57},
+ {0x001e59, 0x001e59},
+ {0x001e5b, 0x001e5b},
+ {0x001e5d, 0x001e5d},
+ {0x001e5f, 0x001e5f},
+ {0x001e61, 0x001e61},
+ {0x001e63, 0x001e63},
+ {0x001e65, 0x001e65},
+ {0x001e67, 0x001e67},
+ {0x001e69, 0x001e69},
+ {0x001e6b, 0x001e6b},
+ {0x001e6d, 0x001e6d},
+ {0x001e6f, 0x001e6f},
+ {0x001e71, 0x001e71},
+ {0x001e73, 0x001e73},
+ {0x001e75, 0x001e75},
+ {0x001e77, 0x001e77},
+ {0x001e79, 0x001e79},
+ {0x001e7b, 0x001e7b},
+ {0x001e7d, 0x001e7d},
+ {0x001e7f, 0x001e7f},
+ {0x001e81, 0x001e81},
+ {0x001e83, 0x001e83},
+ {0x001e85, 0x001e85},
+ {0x001e87, 0x001e87},
+ {0x001e89, 0x001e89},
+ {0x001e8b, 0x001e8b},
+ {0x001e8d, 0x001e8d},
+ {0x001e8f, 0x001e8f},
+ {0x001e91, 0x001e91},
+ {0x001e93, 0x001e93},
+ {0x001e95, 0x001e9d},
+ {0x001e9f, 0x001e9f},
+ {0x001ea1, 0x001ea1},
+ {0x001ea3, 0x001ea3},
+ {0x001ea5, 0x001ea5},
+ {0x001ea7, 0x001ea7},
+ {0x001ea9, 0x001ea9},
+ {0x001eab, 0x001eab},
+ {0x001ead, 0x001ead},
+ {0x001eaf, 0x001eaf},
+ {0x001eb1, 0x001eb1},
+ {0x001eb3, 0x001eb3},
+ {0x001eb5, 0x001eb5},
+ {0x001eb7, 0x001eb7},
+ {0x001eb9, 0x001eb9},
+ {0x001ebb, 0x001ebb},
+ {0x001ebd, 0x001ebd},
+ {0x001ebf, 0x001ebf},
+ {0x001ec1, 0x001ec1},
+ {0x001ec3, 0x001ec3},
+ {0x001ec5, 0x001ec5},
+ {0x001ec7, 0x001ec7},
+ {0x001ec9, 0x001ec9},
+ {0x001ecb, 0x001ecb},
+ {0x001ecd, 0x001ecd},
+ {0x001ecf, 0x001ecf},
+ {0x001ed1, 0x001ed1},
+ {0x001ed3, 0x001ed3},
+ {0x001ed5, 0x001ed5},
+ {0x001ed7, 0x001ed7},
+ {0x001ed9, 0x001ed9},
+ {0x001edb, 0x001edb},
+ {0x001edd, 0x001edd},
+ {0x001edf, 0x001edf},
+ {0x001ee1, 0x001ee1},
+ {0x001ee3, 0x001ee3},
+ {0x001ee5, 0x001ee5},
+ {0x001ee7, 0x001ee7},
+ {0x001ee9, 0x001ee9},
+ {0x001eeb, 0x001eeb},
+ {0x001eed, 0x001eed},
+ {0x001eef, 0x001eef},
+ {0x001ef1, 0x001ef1},
+ {0x001ef3, 0x001ef3},
+ {0x001ef5, 0x001ef5},
+ {0x001ef7, 0x001ef7},
+ {0x001ef9, 0x001ef9},
+ {0x001efb, 0x001efb},
+ {0x001efd, 0x001efd},
+ {0x001eff, 0x001f07},
+ {0x001f10, 0x001f15},
+ {0x001f20, 0x001f27},
+ {0x001f30, 0x001f37},
+ {0x001f40, 0x001f45},
+ {0x001f50, 0x001f57},
+ {0x001f60, 0x001f67},
+ {0x001f70, 0x001f7d},
+ {0x001f80, 0x001f87},
+ {0x001f90, 0x001f97},
+ {0x001fa0, 0x001fa7},
+ {0x001fb0, 0x001fb4},
+ {0x001fb6, 0x001fb7},
+ {0x001fbe, 0x001fbe},
+ {0x001fc2, 0x001fc4},
+ {0x001fc6, 0x001fc7},
+ {0x001fd0, 0x001fd3},
+ {0x001fd6, 0x001fd7},
+ {0x001fe0, 0x001fe7},
+ {0x001ff2, 0x001ff4},
+ {0x001ff6, 0x001ff7},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x00210a, 0x00210a},
+ {0x00210e, 0x00210f},
+ {0x002113, 0x002113},
+ {0x00212f, 0x00212f},
+ {0x002134, 0x002134},
+ {0x002139, 0x002139},
+ {0x00213c, 0x00213d},
+ {0x002146, 0x002149},
+ {0x00214e, 0x00214e},
+ {0x002170, 0x00217f},
+ {0x002184, 0x002184},
+ {0x0024d0, 0x0024e9},
+ {0x002c30, 0x002c5f},
+ {0x002c61, 0x002c61},
+ {0x002c65, 0x002c66},
+ {0x002c68, 0x002c68},
+ {0x002c6a, 0x002c6a},
+ {0x002c6c, 0x002c6c},
+ {0x002c71, 0x002c71},
+ {0x002c73, 0x002c74},
+ {0x002c76, 0x002c7b},
+ {0x002c7c, 0x002c7d},
+ {0x002c81, 0x002c81},
+ {0x002c83, 0x002c83},
+ {0x002c85, 0x002c85},
+ {0x002c87, 0x002c87},
+ {0x002c89, 0x002c89},
+ {0x002c8b, 0x002c8b},
+ {0x002c8d, 0x002c8d},
+ {0x002c8f, 0x002c8f},
+ {0x002c91, 0x002c91},
+ {0x002c93, 0x002c93},
+ {0x002c95, 0x002c95},
+ {0x002c97, 0x002c97},
+ {0x002c99, 0x002c99},
+ {0x002c9b, 0x002c9b},
+ {0x002c9d, 0x002c9d},
+ {0x002c9f, 0x002c9f},
+ {0x002ca1, 0x002ca1},
+ {0x002ca3, 0x002ca3},
+ {0x002ca5, 0x002ca5},
+ {0x002ca7, 0x002ca7},
+ {0x002ca9, 0x002ca9},
+ {0x002cab, 0x002cab},
+ {0x002cad, 0x002cad},
+ {0x002caf, 0x002caf},
+ {0x002cb1, 0x002cb1},
+ {0x002cb3, 0x002cb3},
+ {0x002cb5, 0x002cb5},
+ {0x002cb7, 0x002cb7},
+ {0x002cb9, 0x002cb9},
+ {0x002cbb, 0x002cbb},
+ {0x002cbd, 0x002cbd},
+ {0x002cbf, 0x002cbf},
+ {0x002cc1, 0x002cc1},
+ {0x002cc3, 0x002cc3},
+ {0x002cc5, 0x002cc5},
+ {0x002cc7, 0x002cc7},
+ {0x002cc9, 0x002cc9},
+ {0x002ccb, 0x002ccb},
+ {0x002ccd, 0x002ccd},
+ {0x002ccf, 0x002ccf},
+ {0x002cd1, 0x002cd1},
+ {0x002cd3, 0x002cd3},
+ {0x002cd5, 0x002cd5},
+ {0x002cd7, 0x002cd7},
+ {0x002cd9, 0x002cd9},
+ {0x002cdb, 0x002cdb},
+ {0x002cdd, 0x002cdd},
+ {0x002cdf, 0x002cdf},
+ {0x002ce1, 0x002ce1},
+ {0x002ce3, 0x002ce4},
+ {0x002cec, 0x002cec},
+ {0x002cee, 0x002cee},
+ {0x002cf3, 0x002cf3},
+ {0x002d00, 0x002d25},
+ {0x002d27, 0x002d27},
+ {0x002d2d, 0x002d2d},
+ {0x00a641, 0x00a641},
+ {0x00a643, 0x00a643},
+ {0x00a645, 0x00a645},
+ {0x00a647, 0x00a647},
+ {0x00a649, 0x00a649},
+ {0x00a64b, 0x00a64b},
+ {0x00a64d, 0x00a64d},
+ {0x00a64f, 0x00a64f},
+ {0x00a651, 0x00a651},
+ {0x00a653, 0x00a653},
+ {0x00a655, 0x00a655},
+ {0x00a657, 0x00a657},
+ {0x00a659, 0x00a659},
+ {0x00a65b, 0x00a65b},
+ {0x00a65d, 0x00a65d},
+ {0x00a65f, 0x00a65f},
+ {0x00a661, 0x00a661},
+ {0x00a663, 0x00a663},
+ {0x00a665, 0x00a665},
+ {0x00a667, 0x00a667},
+ {0x00a669, 0x00a669},
+ {0x00a66b, 0x00a66b},
+ {0x00a66d, 0x00a66d},
+ {0x00a681, 0x00a681},
+ {0x00a683, 0x00a683},
+ {0x00a685, 0x00a685},
+ {0x00a687, 0x00a687},
+ {0x00a689, 0x00a689},
+ {0x00a68b, 0x00a68b},
+ {0x00a68d, 0x00a68d},
+ {0x00a68f, 0x00a68f},
+ {0x00a691, 0x00a691},
+ {0x00a693, 0x00a693},
+ {0x00a695, 0x00a695},
+ {0x00a697, 0x00a697},
+ {0x00a699, 0x00a699},
+ {0x00a69b, 0x00a69b},
+ {0x00a69c, 0x00a69d},
+ {0x00a723, 0x00a723},
+ {0x00a725, 0x00a725},
+ {0x00a727, 0x00a727},
+ {0x00a729, 0x00a729},
+ {0x00a72b, 0x00a72b},
+ {0x00a72d, 0x00a72d},
+ {0x00a72f, 0x00a731},
+ {0x00a733, 0x00a733},
+ {0x00a735, 0x00a735},
+ {0x00a737, 0x00a737},
+ {0x00a739, 0x00a739},
+ {0x00a73b, 0x00a73b},
+ {0x00a73d, 0x00a73d},
+ {0x00a73f, 0x00a73f},
+ {0x00a741, 0x00a741},
+ {0x00a743, 0x00a743},
+ {0x00a745, 0x00a745},
+ {0x00a747, 0x00a747},
+ {0x00a749, 0x00a749},
+ {0x00a74b, 0x00a74b},
+ {0x00a74d, 0x00a74d},
+ {0x00a74f, 0x00a74f},
+ {0x00a751, 0x00a751},
+ {0x00a753, 0x00a753},
+ {0x00a755, 0x00a755},
+ {0x00a757, 0x00a757},
+ {0x00a759, 0x00a759},
+ {0x00a75b, 0x00a75b},
+ {0x00a75d, 0x00a75d},
+ {0x00a75f, 0x00a75f},
+ {0x00a761, 0x00a761},
+ {0x00a763, 0x00a763},
+ {0x00a765, 0x00a765},
+ {0x00a767, 0x00a767},
+ {0x00a769, 0x00a769},
+ {0x00a76b, 0x00a76b},
+ {0x00a76d, 0x00a76d},
+ {0x00a76f, 0x00a76f},
+ {0x00a770, 0x00a770},
+ {0x00a771, 0x00a778},
+ {0x00a77a, 0x00a77a},
+ {0x00a77c, 0x00a77c},
+ {0x00a77f, 0x00a77f},
+ {0x00a781, 0x00a781},
+ {0x00a783, 0x00a783},
+ {0x00a785, 0x00a785},
+ {0x00a787, 0x00a787},
+ {0x00a78c, 0x00a78c},
+ {0x00a78e, 0x00a78e},
+ {0x00a791, 0x00a791},
+ {0x00a793, 0x00a795},
+ {0x00a797, 0x00a797},
+ {0x00a799, 0x00a799},
+ {0x00a79b, 0x00a79b},
+ {0x00a79d, 0x00a79d},
+ {0x00a79f, 0x00a79f},
+ {0x00a7a1, 0x00a7a1},
+ {0x00a7a3, 0x00a7a3},
+ {0x00a7a5, 0x00a7a5},
+ {0x00a7a7, 0x00a7a7},
+ {0x00a7a9, 0x00a7a9},
+ {0x00a7af, 0x00a7af},
+ {0x00a7b5, 0x00a7b5},
+ {0x00a7b7, 0x00a7b7},
+ {0x00a7b9, 0x00a7b9},
+ {0x00a7bb, 0x00a7bb},
+ {0x00a7bd, 0x00a7bd},
+ {0x00a7bf, 0x00a7bf},
+ {0x00a7c1, 0x00a7c1},
+ {0x00a7c3, 0x00a7c3},
+ {0x00a7c8, 0x00a7c8},
+ {0x00a7ca, 0x00a7ca},
+ {0x00a7d1, 0x00a7d1},
+ {0x00a7d3, 0x00a7d3},
+ {0x00a7d5, 0x00a7d5},
+ {0x00a7d7, 0x00a7d7},
+ {0x00a7d9, 0x00a7d9},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f6, 0x00a7f6},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a7fa, 0x00a7fa},
+ {0x00ab30, 0x00ab5a},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab60, 0x00ab68},
+ {0x00ab69, 0x00ab69},
+ {0x00ab70, 0x00abbf},
+ {0x00fb00, 0x00fb06},
+ {0x00fb13, 0x00fb17},
+ {0x00ff41, 0x00ff5a},
+ {0x010428, 0x01044f},
+ {0x0104d8, 0x0104fb},
+ {0x010597, 0x0105a1},
+ {0x0105a3, 0x0105b1},
+ {0x0105b3, 0x0105b9},
+ {0x0105bb, 0x0105bc},
+ {0x010780, 0x010780},
+ {0x010783, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010cc0, 0x010cf2},
+ {0x0118c0, 0x0118df},
+ {0x016e60, 0x016e7f},
+ {0x01d41a, 0x01d433},
+ {0x01d44e, 0x01d454},
+ {0x01d456, 0x01d467},
+ {0x01d482, 0x01d49b},
+ {0x01d4b6, 0x01d4b9},
+ {0x01d4bb, 0x01d4bb},
+ {0x01d4bd, 0x01d4c3},
+ {0x01d4c5, 0x01d4cf},
+ {0x01d4ea, 0x01d503},
+ {0x01d51e, 0x01d537},
+ {0x01d552, 0x01d56b},
+ {0x01d586, 0x01d59f},
+ {0x01d5ba, 0x01d5d3},
+ {0x01d5ee, 0x01d607},
+ {0x01d622, 0x01d63b},
+ {0x01d656, 0x01d66f},
+ {0x01d68a, 0x01d6a5},
+ {0x01d6c2, 0x01d6da},
+ {0x01d6dc, 0x01d6e1},
+ {0x01d6fc, 0x01d714},
+ {0x01d716, 0x01d71b},
+ {0x01d736, 0x01d74e},
+ {0x01d750, 0x01d755},
+ {0x01d770, 0x01d788},
+ {0x01d78a, 0x01d78f},
+ {0x01d7aa, 0x01d7c2},
+ {0x01d7c4, 0x01d7c9},
+ {0x01d7cb, 0x01d7cb},
+ {0x01df00, 0x01df09},
+ {0x01df0b, 0x01df1e},
+ {0x01df25, 0x01df2a},
+ {0x01e030, 0x01e06d},
+ {0x01e922, 0x01e943},
+};
+
+/* table of Unicode codepoint ranges of Uppercase characters */
+static const pg_unicode_range unicode_uppercase[651] =
+{
+ {0x000041, 0x00005a},
+ {0x0000c0, 0x0000d6},
+ {0x0000d8, 0x0000de},
+ {0x000100, 0x000100},
+ {0x000102, 0x000102},
+ {0x000104, 0x000104},
+ {0x000106, 0x000106},
+ {0x000108, 0x000108},
+ {0x00010a, 0x00010a},
+ {0x00010c, 0x00010c},
+ {0x00010e, 0x00010e},
+ {0x000110, 0x000110},
+ {0x000112, 0x000112},
+ {0x000114, 0x000114},
+ {0x000116, 0x000116},
+ {0x000118, 0x000118},
+ {0x00011a, 0x00011a},
+ {0x00011c, 0x00011c},
+ {0x00011e, 0x00011e},
+ {0x000120, 0x000120},
+ {0x000122, 0x000122},
+ {0x000124, 0x000124},
+ {0x000126, 0x000126},
+ {0x000128, 0x000128},
+ {0x00012a, 0x00012a},
+ {0x00012c, 0x00012c},
+ {0x00012e, 0x00012e},
+ {0x000130, 0x000130},
+ {0x000132, 0x000132},
+ {0x000134, 0x000134},
+ {0x000136, 0x000136},
+ {0x000139, 0x000139},
+ {0x00013b, 0x00013b},
+ {0x00013d, 0x00013d},
+ {0x00013f, 0x00013f},
+ {0x000141, 0x000141},
+ {0x000143, 0x000143},
+ {0x000145, 0x000145},
+ {0x000147, 0x000147},
+ {0x00014a, 0x00014a},
+ {0x00014c, 0x00014c},
+ {0x00014e, 0x00014e},
+ {0x000150, 0x000150},
+ {0x000152, 0x000152},
+ {0x000154, 0x000154},
+ {0x000156, 0x000156},
+ {0x000158, 0x000158},
+ {0x00015a, 0x00015a},
+ {0x00015c, 0x00015c},
+ {0x00015e, 0x00015e},
+ {0x000160, 0x000160},
+ {0x000162, 0x000162},
+ {0x000164, 0x000164},
+ {0x000166, 0x000166},
+ {0x000168, 0x000168},
+ {0x00016a, 0x00016a},
+ {0x00016c, 0x00016c},
+ {0x00016e, 0x00016e},
+ {0x000170, 0x000170},
+ {0x000172, 0x000172},
+ {0x000174, 0x000174},
+ {0x000176, 0x000176},
+ {0x000178, 0x000179},
+ {0x00017b, 0x00017b},
+ {0x00017d, 0x00017d},
+ {0x000181, 0x000182},
+ {0x000184, 0x000184},
+ {0x000186, 0x000187},
+ {0x000189, 0x00018b},
+ {0x00018e, 0x000191},
+ {0x000193, 0x000194},
+ {0x000196, 0x000198},
+ {0x00019c, 0x00019d},
+ {0x00019f, 0x0001a0},
+ {0x0001a2, 0x0001a2},
+ {0x0001a4, 0x0001a4},
+ {0x0001a6, 0x0001a7},
+ {0x0001a9, 0x0001a9},
+ {0x0001ac, 0x0001ac},
+ {0x0001ae, 0x0001af},
+ {0x0001b1, 0x0001b3},
+ {0x0001b5, 0x0001b5},
+ {0x0001b7, 0x0001b8},
+ {0x0001bc, 0x0001bc},
+ {0x0001c4, 0x0001c4},
+ {0x0001c7, 0x0001c7},
+ {0x0001ca, 0x0001ca},
+ {0x0001cd, 0x0001cd},
+ {0x0001cf, 0x0001cf},
+ {0x0001d1, 0x0001d1},
+ {0x0001d3, 0x0001d3},
+ {0x0001d5, 0x0001d5},
+ {0x0001d7, 0x0001d7},
+ {0x0001d9, 0x0001d9},
+ {0x0001db, 0x0001db},
+ {0x0001de, 0x0001de},
+ {0x0001e0, 0x0001e0},
+ {0x0001e2, 0x0001e2},
+ {0x0001e4, 0x0001e4},
+ {0x0001e6, 0x0001e6},
+ {0x0001e8, 0x0001e8},
+ {0x0001ea, 0x0001ea},
+ {0x0001ec, 0x0001ec},
+ {0x0001ee, 0x0001ee},
+ {0x0001f1, 0x0001f1},
+ {0x0001f4, 0x0001f4},
+ {0x0001f6, 0x0001f8},
+ {0x0001fa, 0x0001fa},
+ {0x0001fc, 0x0001fc},
+ {0x0001fe, 0x0001fe},
+ {0x000200, 0x000200},
+ {0x000202, 0x000202},
+ {0x000204, 0x000204},
+ {0x000206, 0x000206},
+ {0x000208, 0x000208},
+ {0x00020a, 0x00020a},
+ {0x00020c, 0x00020c},
+ {0x00020e, 0x00020e},
+ {0x000210, 0x000210},
+ {0x000212, 0x000212},
+ {0x000214, 0x000214},
+ {0x000216, 0x000216},
+ {0x000218, 0x000218},
+ {0x00021a, 0x00021a},
+ {0x00021c, 0x00021c},
+ {0x00021e, 0x00021e},
+ {0x000220, 0x000220},
+ {0x000222, 0x000222},
+ {0x000224, 0x000224},
+ {0x000226, 0x000226},
+ {0x000228, 0x000228},
+ {0x00022a, 0x00022a},
+ {0x00022c, 0x00022c},
+ {0x00022e, 0x00022e},
+ {0x000230, 0x000230},
+ {0x000232, 0x000232},
+ {0x00023a, 0x00023b},
+ {0x00023d, 0x00023e},
+ {0x000241, 0x000241},
+ {0x000243, 0x000246},
+ {0x000248, 0x000248},
+ {0x00024a, 0x00024a},
+ {0x00024c, 0x00024c},
+ {0x00024e, 0x00024e},
+ {0x000370, 0x000370},
+ {0x000372, 0x000372},
+ {0x000376, 0x000376},
+ {0x00037f, 0x00037f},
+ {0x000386, 0x000386},
+ {0x000388, 0x00038a},
+ {0x00038c, 0x00038c},
+ {0x00038e, 0x00038f},
+ {0x000391, 0x0003a1},
+ {0x0003a3, 0x0003ab},
+ {0x0003cf, 0x0003cf},
+ {0x0003d2, 0x0003d4},
+ {0x0003d8, 0x0003d8},
+ {0x0003da, 0x0003da},
+ {0x0003dc, 0x0003dc},
+ {0x0003de, 0x0003de},
+ {0x0003e0, 0x0003e0},
+ {0x0003e2, 0x0003e2},
+ {0x0003e4, 0x0003e4},
+ {0x0003e6, 0x0003e6},
+ {0x0003e8, 0x0003e8},
+ {0x0003ea, 0x0003ea},
+ {0x0003ec, 0x0003ec},
+ {0x0003ee, 0x0003ee},
+ {0x0003f4, 0x0003f4},
+ {0x0003f7, 0x0003f7},
+ {0x0003f9, 0x0003fa},
+ {0x0003fd, 0x00042f},
+ {0x000460, 0x000460},
+ {0x000462, 0x000462},
+ {0x000464, 0x000464},
+ {0x000466, 0x000466},
+ {0x000468, 0x000468},
+ {0x00046a, 0x00046a},
+ {0x00046c, 0x00046c},
+ {0x00046e, 0x00046e},
+ {0x000470, 0x000470},
+ {0x000472, 0x000472},
+ {0x000474, 0x000474},
+ {0x000476, 0x000476},
+ {0x000478, 0x000478},
+ {0x00047a, 0x00047a},
+ {0x00047c, 0x00047c},
+ {0x00047e, 0x00047e},
+ {0x000480, 0x000480},
+ {0x00048a, 0x00048a},
+ {0x00048c, 0x00048c},
+ {0x00048e, 0x00048e},
+ {0x000490, 0x000490},
+ {0x000492, 0x000492},
+ {0x000494, 0x000494},
+ {0x000496, 0x000496},
+ {0x000498, 0x000498},
+ {0x00049a, 0x00049a},
+ {0x00049c, 0x00049c},
+ {0x00049e, 0x00049e},
+ {0x0004a0, 0x0004a0},
+ {0x0004a2, 0x0004a2},
+ {0x0004a4, 0x0004a4},
+ {0x0004a6, 0x0004a6},
+ {0x0004a8, 0x0004a8},
+ {0x0004aa, 0x0004aa},
+ {0x0004ac, 0x0004ac},
+ {0x0004ae, 0x0004ae},
+ {0x0004b0, 0x0004b0},
+ {0x0004b2, 0x0004b2},
+ {0x0004b4, 0x0004b4},
+ {0x0004b6, 0x0004b6},
+ {0x0004b8, 0x0004b8},
+ {0x0004ba, 0x0004ba},
+ {0x0004bc, 0x0004bc},
+ {0x0004be, 0x0004be},
+ {0x0004c0, 0x0004c1},
+ {0x0004c3, 0x0004c3},
+ {0x0004c5, 0x0004c5},
+ {0x0004c7, 0x0004c7},
+ {0x0004c9, 0x0004c9},
+ {0x0004cb, 0x0004cb},
+ {0x0004cd, 0x0004cd},
+ {0x0004d0, 0x0004d0},
+ {0x0004d2, 0x0004d2},
+ {0x0004d4, 0x0004d4},
+ {0x0004d6, 0x0004d6},
+ {0x0004d8, 0x0004d8},
+ {0x0004da, 0x0004da},
+ {0x0004dc, 0x0004dc},
+ {0x0004de, 0x0004de},
+ {0x0004e0, 0x0004e0},
+ {0x0004e2, 0x0004e2},
+ {0x0004e4, 0x0004e4},
+ {0x0004e6, 0x0004e6},
+ {0x0004e8, 0x0004e8},
+ {0x0004ea, 0x0004ea},
+ {0x0004ec, 0x0004ec},
+ {0x0004ee, 0x0004ee},
+ {0x0004f0, 0x0004f0},
+ {0x0004f2, 0x0004f2},
+ {0x0004f4, 0x0004f4},
+ {0x0004f6, 0x0004f6},
+ {0x0004f8, 0x0004f8},
+ {0x0004fa, 0x0004fa},
+ {0x0004fc, 0x0004fc},
+ {0x0004fe, 0x0004fe},
+ {0x000500, 0x000500},
+ {0x000502, 0x000502},
+ {0x000504, 0x000504},
+ {0x000506, 0x000506},
+ {0x000508, 0x000508},
+ {0x00050a, 0x00050a},
+ {0x00050c, 0x00050c},
+ {0x00050e, 0x00050e},
+ {0x000510, 0x000510},
+ {0x000512, 0x000512},
+ {0x000514, 0x000514},
+ {0x000516, 0x000516},
+ {0x000518, 0x000518},
+ {0x00051a, 0x00051a},
+ {0x00051c, 0x00051c},
+ {0x00051e, 0x00051e},
+ {0x000520, 0x000520},
+ {0x000522, 0x000522},
+ {0x000524, 0x000524},
+ {0x000526, 0x000526},
+ {0x000528, 0x000528},
+ {0x00052a, 0x00052a},
+ {0x00052c, 0x00052c},
+ {0x00052e, 0x00052e},
+ {0x000531, 0x000556},
+ {0x0010a0, 0x0010c5},
+ {0x0010c7, 0x0010c7},
+ {0x0010cd, 0x0010cd},
+ {0x0013a0, 0x0013f5},
+ {0x001c90, 0x001cba},
+ {0x001cbd, 0x001cbf},
+ {0x001e00, 0x001e00},
+ {0x001e02, 0x001e02},
+ {0x001e04, 0x001e04},
+ {0x001e06, 0x001e06},
+ {0x001e08, 0x001e08},
+ {0x001e0a, 0x001e0a},
+ {0x001e0c, 0x001e0c},
+ {0x001e0e, 0x001e0e},
+ {0x001e10, 0x001e10},
+ {0x001e12, 0x001e12},
+ {0x001e14, 0x001e14},
+ {0x001e16, 0x001e16},
+ {0x001e18, 0x001e18},
+ {0x001e1a, 0x001e1a},
+ {0x001e1c, 0x001e1c},
+ {0x001e1e, 0x001e1e},
+ {0x001e20, 0x001e20},
+ {0x001e22, 0x001e22},
+ {0x001e24, 0x001e24},
+ {0x001e26, 0x001e26},
+ {0x001e28, 0x001e28},
+ {0x001e2a, 0x001e2a},
+ {0x001e2c, 0x001e2c},
+ {0x001e2e, 0x001e2e},
+ {0x001e30, 0x001e30},
+ {0x001e32, 0x001e32},
+ {0x001e34, 0x001e34},
+ {0x001e36, 0x001e36},
+ {0x001e38, 0x001e38},
+ {0x001e3a, 0x001e3a},
+ {0x001e3c, 0x001e3c},
+ {0x001e3e, 0x001e3e},
+ {0x001e40, 0x001e40},
+ {0x001e42, 0x001e42},
+ {0x001e44, 0x001e44},
+ {0x001e46, 0x001e46},
+ {0x001e48, 0x001e48},
+ {0x001e4a, 0x001e4a},
+ {0x001e4c, 0x001e4c},
+ {0x001e4e, 0x001e4e},
+ {0x001e50, 0x001e50},
+ {0x001e52, 0x001e52},
+ {0x001e54, 0x001e54},
+ {0x001e56, 0x001e56},
+ {0x001e58, 0x001e58},
+ {0x001e5a, 0x001e5a},
+ {0x001e5c, 0x001e5c},
+ {0x001e5e, 0x001e5e},
+ {0x001e60, 0x001e60},
+ {0x001e62, 0x001e62},
+ {0x001e64, 0x001e64},
+ {0x001e66, 0x001e66},
+ {0x001e68, 0x001e68},
+ {0x001e6a, 0x001e6a},
+ {0x001e6c, 0x001e6c},
+ {0x001e6e, 0x001e6e},
+ {0x001e70, 0x001e70},
+ {0x001e72, 0x001e72},
+ {0x001e74, 0x001e74},
+ {0x001e76, 0x001e76},
+ {0x001e78, 0x001e78},
+ {0x001e7a, 0x001e7a},
+ {0x001e7c, 0x001e7c},
+ {0x001e7e, 0x001e7e},
+ {0x001e80, 0x001e80},
+ {0x001e82, 0x001e82},
+ {0x001e84, 0x001e84},
+ {0x001e86, 0x001e86},
+ {0x001e88, 0x001e88},
+ {0x001e8a, 0x001e8a},
+ {0x001e8c, 0x001e8c},
+ {0x001e8e, 0x001e8e},
+ {0x001e90, 0x001e90},
+ {0x001e92, 0x001e92},
+ {0x001e94, 0x001e94},
+ {0x001e9e, 0x001e9e},
+ {0x001ea0, 0x001ea0},
+ {0x001ea2, 0x001ea2},
+ {0x001ea4, 0x001ea4},
+ {0x001ea6, 0x001ea6},
+ {0x001ea8, 0x001ea8},
+ {0x001eaa, 0x001eaa},
+ {0x001eac, 0x001eac},
+ {0x001eae, 0x001eae},
+ {0x001eb0, 0x001eb0},
+ {0x001eb2, 0x001eb2},
+ {0x001eb4, 0x001eb4},
+ {0x001eb6, 0x001eb6},
+ {0x001eb8, 0x001eb8},
+ {0x001eba, 0x001eba},
+ {0x001ebc, 0x001ebc},
+ {0x001ebe, 0x001ebe},
+ {0x001ec0, 0x001ec0},
+ {0x001ec2, 0x001ec2},
+ {0x001ec4, 0x001ec4},
+ {0x001ec6, 0x001ec6},
+ {0x001ec8, 0x001ec8},
+ {0x001eca, 0x001eca},
+ {0x001ecc, 0x001ecc},
+ {0x001ece, 0x001ece},
+ {0x001ed0, 0x001ed0},
+ {0x001ed2, 0x001ed2},
+ {0x001ed4, 0x001ed4},
+ {0x001ed6, 0x001ed6},
+ {0x001ed8, 0x001ed8},
+ {0x001eda, 0x001eda},
+ {0x001edc, 0x001edc},
+ {0x001ede, 0x001ede},
+ {0x001ee0, 0x001ee0},
+ {0x001ee2, 0x001ee2},
+ {0x001ee4, 0x001ee4},
+ {0x001ee6, 0x001ee6},
+ {0x001ee8, 0x001ee8},
+ {0x001eea, 0x001eea},
+ {0x001eec, 0x001eec},
+ {0x001eee, 0x001eee},
+ {0x001ef0, 0x001ef0},
+ {0x001ef2, 0x001ef2},
+ {0x001ef4, 0x001ef4},
+ {0x001ef6, 0x001ef6},
+ {0x001ef8, 0x001ef8},
+ {0x001efa, 0x001efa},
+ {0x001efc, 0x001efc},
+ {0x001efe, 0x001efe},
+ {0x001f08, 0x001f0f},
+ {0x001f18, 0x001f1d},
+ {0x001f28, 0x001f2f},
+ {0x001f38, 0x001f3f},
+ {0x001f48, 0x001f4d},
+ {0x001f59, 0x001f59},
+ {0x001f5b, 0x001f5b},
+ {0x001f5d, 0x001f5d},
+ {0x001f5f, 0x001f5f},
+ {0x001f68, 0x001f6f},
+ {0x001fb8, 0x001fbb},
+ {0x001fc8, 0x001fcb},
+ {0x001fd8, 0x001fdb},
+ {0x001fe8, 0x001fec},
+ {0x001ff8, 0x001ffb},
+ {0x002102, 0x002102},
+ {0x002107, 0x002107},
+ {0x00210b, 0x00210d},
+ {0x002110, 0x002112},
+ {0x002115, 0x002115},
+ {0x002119, 0x00211d},
+ {0x002124, 0x002124},
+ {0x002126, 0x002126},
+ {0x002128, 0x002128},
+ {0x00212a, 0x00212d},
+ {0x002130, 0x002133},
+ {0x00213e, 0x00213f},
+ {0x002145, 0x002145},
+ {0x002160, 0x00216f},
+ {0x002183, 0x002183},
+ {0x0024b6, 0x0024cf},
+ {0x002c00, 0x002c2f},
+ {0x002c60, 0x002c60},
+ {0x002c62, 0x002c64},
+ {0x002c67, 0x002c67},
+ {0x002c69, 0x002c69},
+ {0x002c6b, 0x002c6b},
+ {0x002c6d, 0x002c70},
+ {0x002c72, 0x002c72},
+ {0x002c75, 0x002c75},
+ {0x002c7e, 0x002c80},
+ {0x002c82, 0x002c82},
+ {0x002c84, 0x002c84},
+ {0x002c86, 0x002c86},
+ {0x002c88, 0x002c88},
+ {0x002c8a, 0x002c8a},
+ {0x002c8c, 0x002c8c},
+ {0x002c8e, 0x002c8e},
+ {0x002c90, 0x002c90},
+ {0x002c92, 0x002c92},
+ {0x002c94, 0x002c94},
+ {0x002c96, 0x002c96},
+ {0x002c98, 0x002c98},
+ {0x002c9a, 0x002c9a},
+ {0x002c9c, 0x002c9c},
+ {0x002c9e, 0x002c9e},
+ {0x002ca0, 0x002ca0},
+ {0x002ca2, 0x002ca2},
+ {0x002ca4, 0x002ca4},
+ {0x002ca6, 0x002ca6},
+ {0x002ca8, 0x002ca8},
+ {0x002caa, 0x002caa},
+ {0x002cac, 0x002cac},
+ {0x002cae, 0x002cae},
+ {0x002cb0, 0x002cb0},
+ {0x002cb2, 0x002cb2},
+ {0x002cb4, 0x002cb4},
+ {0x002cb6, 0x002cb6},
+ {0x002cb8, 0x002cb8},
+ {0x002cba, 0x002cba},
+ {0x002cbc, 0x002cbc},
+ {0x002cbe, 0x002cbe},
+ {0x002cc0, 0x002cc0},
+ {0x002cc2, 0x002cc2},
+ {0x002cc4, 0x002cc4},
+ {0x002cc6, 0x002cc6},
+ {0x002cc8, 0x002cc8},
+ {0x002cca, 0x002cca},
+ {0x002ccc, 0x002ccc},
+ {0x002cce, 0x002cce},
+ {0x002cd0, 0x002cd0},
+ {0x002cd2, 0x002cd2},
+ {0x002cd4, 0x002cd4},
+ {0x002cd6, 0x002cd6},
+ {0x002cd8, 0x002cd8},
+ {0x002cda, 0x002cda},
+ {0x002cdc, 0x002cdc},
+ {0x002cde, 0x002cde},
+ {0x002ce0, 0x002ce0},
+ {0x002ce2, 0x002ce2},
+ {0x002ceb, 0x002ceb},
+ {0x002ced, 0x002ced},
+ {0x002cf2, 0x002cf2},
+ {0x00a640, 0x00a640},
+ {0x00a642, 0x00a642},
+ {0x00a644, 0x00a644},
+ {0x00a646, 0x00a646},
+ {0x00a648, 0x00a648},
+ {0x00a64a, 0x00a64a},
+ {0x00a64c, 0x00a64c},
+ {0x00a64e, 0x00a64e},
+ {0x00a650, 0x00a650},
+ {0x00a652, 0x00a652},
+ {0x00a654, 0x00a654},
+ {0x00a656, 0x00a656},
+ {0x00a658, 0x00a658},
+ {0x00a65a, 0x00a65a},
+ {0x00a65c, 0x00a65c},
+ {0x00a65e, 0x00a65e},
+ {0x00a660, 0x00a660},
+ {0x00a662, 0x00a662},
+ {0x00a664, 0x00a664},
+ {0x00a666, 0x00a666},
+ {0x00a668, 0x00a668},
+ {0x00a66a, 0x00a66a},
+ {0x00a66c, 0x00a66c},
+ {0x00a680, 0x00a680},
+ {0x00a682, 0x00a682},
+ {0x00a684, 0x00a684},
+ {0x00a686, 0x00a686},
+ {0x00a688, 0x00a688},
+ {0x00a68a, 0x00a68a},
+ {0x00a68c, 0x00a68c},
+ {0x00a68e, 0x00a68e},
+ {0x00a690, 0x00a690},
+ {0x00a692, 0x00a692},
+ {0x00a694, 0x00a694},
+ {0x00a696, 0x00a696},
+ {0x00a698, 0x00a698},
+ {0x00a69a, 0x00a69a},
+ {0x00a722, 0x00a722},
+ {0x00a724, 0x00a724},
+ {0x00a726, 0x00a726},
+ {0x00a728, 0x00a728},
+ {0x00a72a, 0x00a72a},
+ {0x00a72c, 0x00a72c},
+ {0x00a72e, 0x00a72e},
+ {0x00a732, 0x00a732},
+ {0x00a734, 0x00a734},
+ {0x00a736, 0x00a736},
+ {0x00a738, 0x00a738},
+ {0x00a73a, 0x00a73a},
+ {0x00a73c, 0x00a73c},
+ {0x00a73e, 0x00a73e},
+ {0x00a740, 0x00a740},
+ {0x00a742, 0x00a742},
+ {0x00a744, 0x00a744},
+ {0x00a746, 0x00a746},
+ {0x00a748, 0x00a748},
+ {0x00a74a, 0x00a74a},
+ {0x00a74c, 0x00a74c},
+ {0x00a74e, 0x00a74e},
+ {0x00a750, 0x00a750},
+ {0x00a752, 0x00a752},
+ {0x00a754, 0x00a754},
+ {0x00a756, 0x00a756},
+ {0x00a758, 0x00a758},
+ {0x00a75a, 0x00a75a},
+ {0x00a75c, 0x00a75c},
+ {0x00a75e, 0x00a75e},
+ {0x00a760, 0x00a760},
+ {0x00a762, 0x00a762},
+ {0x00a764, 0x00a764},
+ {0x00a766, 0x00a766},
+ {0x00a768, 0x00a768},
+ {0x00a76a, 0x00a76a},
+ {0x00a76c, 0x00a76c},
+ {0x00a76e, 0x00a76e},
+ {0x00a779, 0x00a779},
+ {0x00a77b, 0x00a77b},
+ {0x00a77d, 0x00a77e},
+ {0x00a780, 0x00a780},
+ {0x00a782, 0x00a782},
+ {0x00a784, 0x00a784},
+ {0x00a786, 0x00a786},
+ {0x00a78b, 0x00a78b},
+ {0x00a78d, 0x00a78d},
+ {0x00a790, 0x00a790},
+ {0x00a792, 0x00a792},
+ {0x00a796, 0x00a796},
+ {0x00a798, 0x00a798},
+ {0x00a79a, 0x00a79a},
+ {0x00a79c, 0x00a79c},
+ {0x00a79e, 0x00a79e},
+ {0x00a7a0, 0x00a7a0},
+ {0x00a7a2, 0x00a7a2},
+ {0x00a7a4, 0x00a7a4},
+ {0x00a7a6, 0x00a7a6},
+ {0x00a7a8, 0x00a7a8},
+ {0x00a7aa, 0x00a7ae},
+ {0x00a7b0, 0x00a7b4},
+ {0x00a7b6, 0x00a7b6},
+ {0x00a7b8, 0x00a7b8},
+ {0x00a7ba, 0x00a7ba},
+ {0x00a7bc, 0x00a7bc},
+ {0x00a7be, 0x00a7be},
+ {0x00a7c0, 0x00a7c0},
+ {0x00a7c2, 0x00a7c2},
+ {0x00a7c4, 0x00a7c7},
+ {0x00a7c9, 0x00a7c9},
+ {0x00a7d0, 0x00a7d0},
+ {0x00a7d6, 0x00a7d6},
+ {0x00a7d8, 0x00a7d8},
+ {0x00a7f5, 0x00a7f5},
+ {0x00ff21, 0x00ff3a},
+ {0x010400, 0x010427},
+ {0x0104b0, 0x0104d3},
+ {0x010570, 0x01057a},
+ {0x01057c, 0x01058a},
+ {0x01058c, 0x010592},
+ {0x010594, 0x010595},
+ {0x010c80, 0x010cb2},
+ {0x0118a0, 0x0118bf},
+ {0x016e40, 0x016e5f},
+ {0x01d400, 0x01d419},
+ {0x01d434, 0x01d44d},
+ {0x01d468, 0x01d481},
+ {0x01d49c, 0x01d49c},
+ {0x01d49e, 0x01d49f},
+ {0x01d4a2, 0x01d4a2},
+ {0x01d4a5, 0x01d4a6},
+ {0x01d4a9, 0x01d4ac},
+ {0x01d4ae, 0x01d4b5},
+ {0x01d4d0, 0x01d4e9},
+ {0x01d504, 0x01d505},
+ {0x01d507, 0x01d50a},
+ {0x01d50d, 0x01d514},
+ {0x01d516, 0x01d51c},
+ {0x01d538, 0x01d539},
+ {0x01d53b, 0x01d53e},
+ {0x01d540, 0x01d544},
+ {0x01d546, 0x01d546},
+ {0x01d54a, 0x01d550},
+ {0x01d56c, 0x01d585},
+ {0x01d5a0, 0x01d5b9},
+ {0x01d5d4, 0x01d5ed},
+ {0x01d608, 0x01d621},
+ {0x01d63c, 0x01d655},
+ {0x01d670, 0x01d689},
+ {0x01d6a8, 0x01d6c0},
+ {0x01d6e2, 0x01d6fa},
+ {0x01d71c, 0x01d734},
+ {0x01d756, 0x01d76e},
+ {0x01d790, 0x01d7a8},
+ {0x01d7ca, 0x01d7ca},
+ {0x01e900, 0x01e921},
+ {0x01f130, 0x01f149},
+ {0x01f150, 0x01f169},
+ {0x01f170, 0x01f189},
+};
+
+/* table of Unicode codepoint ranges of Case_Ignorable characters */
+static const pg_unicode_range unicode_case_ignorable[491] =
+{
+ {0x000027, 0x000027},
+ {0x00002e, 0x00002e},
+ {0x00003a, 0x00003a},
+ {0x00005e, 0x00005e},
+ {0x000060, 0x000060},
+ {0x0000a8, 0x0000a8},
+ {0x0000ad, 0x0000ad},
+ {0x0000af, 0x0000af},
+ {0x0000b4, 0x0000b4},
+ {0x0000b7, 0x0000b7},
+ {0x0000b8, 0x0000b8},
+ {0x0002b0, 0x0002c1},
+ {0x0002c2, 0x0002c5},
+ {0x0002c6, 0x0002d1},
+ {0x0002d2, 0x0002df},
+ {0x0002e0, 0x0002e4},
+ {0x0002e5, 0x0002eb},
+ {0x0002ec, 0x0002ec},
+ {0x0002ed, 0x0002ed},
+ {0x0002ee, 0x0002ee},
+ {0x0002ef, 0x0002ff},
+ {0x000300, 0x00036f},
+ {0x000374, 0x000374},
+ {0x000375, 0x000375},
+ {0x00037a, 0x00037a},
+ {0x000384, 0x000385},
+ {0x000387, 0x000387},
+ {0x000483, 0x000487},
+ {0x000488, 0x000489},
+ {0x000559, 0x000559},
+ {0x00055f, 0x00055f},
+ {0x000591, 0x0005bd},
+ {0x0005bf, 0x0005bf},
+ {0x0005c1, 0x0005c2},
+ {0x0005c4, 0x0005c5},
+ {0x0005c7, 0x0005c7},
+ {0x0005f4, 0x0005f4},
+ {0x000600, 0x000605},
+ {0x000610, 0x00061a},
+ {0x00061c, 0x00061c},
+ {0x000640, 0x000640},
+ {0x00064b, 0x00065f},
+ {0x000670, 0x000670},
+ {0x0006d6, 0x0006dc},
+ {0x0006dd, 0x0006dd},
+ {0x0006df, 0x0006e4},
+ {0x0006e5, 0x0006e6},
+ {0x0006e7, 0x0006e8},
+ {0x0006ea, 0x0006ed},
+ {0x00070f, 0x00070f},
+ {0x000711, 0x000711},
+ {0x000730, 0x00074a},
+ {0x0007a6, 0x0007b0},
+ {0x0007eb, 0x0007f3},
+ {0x0007f4, 0x0007f5},
+ {0x0007fa, 0x0007fa},
+ {0x0007fd, 0x0007fd},
+ {0x000816, 0x000819},
+ {0x00081a, 0x00081a},
+ {0x00081b, 0x000823},
+ {0x000824, 0x000824},
+ {0x000825, 0x000827},
+ {0x000828, 0x000828},
+ {0x000829, 0x00082d},
+ {0x000859, 0x00085b},
+ {0x000888, 0x000888},
+ {0x000890, 0x000891},
+ {0x000898, 0x00089f},
+ {0x0008c9, 0x0008c9},
+ {0x0008ca, 0x0008e1},
+ {0x0008e2, 0x0008e2},
+ {0x0008e3, 0x000902},
+ {0x00093a, 0x00093a},
+ {0x00093c, 0x00093c},
+ {0x000941, 0x000948},
+ {0x00094d, 0x00094d},
+ {0x000951, 0x000957},
+ {0x000962, 0x000963},
+ {0x000971, 0x000971},
+ {0x000981, 0x000981},
+ {0x0009bc, 0x0009bc},
+ {0x0009c1, 0x0009c4},
+ {0x0009cd, 0x0009cd},
+ {0x0009e2, 0x0009e3},
+ {0x0009fe, 0x0009fe},
+ {0x000a01, 0x000a02},
+ {0x000a3c, 0x000a3c},
+ {0x000a41, 0x000a42},
+ {0x000a47, 0x000a48},
+ {0x000a4b, 0x000a4d},
+ {0x000a51, 0x000a51},
+ {0x000a70, 0x000a71},
+ {0x000a75, 0x000a75},
+ {0x000a81, 0x000a82},
+ {0x000abc, 0x000abc},
+ {0x000ac1, 0x000ac5},
+ {0x000ac7, 0x000ac8},
+ {0x000acd, 0x000acd},
+ {0x000ae2, 0x000ae3},
+ {0x000afa, 0x000aff},
+ {0x000b01, 0x000b01},
+ {0x000b3c, 0x000b3c},
+ {0x000b3f, 0x000b3f},
+ {0x000b41, 0x000b44},
+ {0x000b4d, 0x000b4d},
+ {0x000b55, 0x000b56},
+ {0x000b62, 0x000b63},
+ {0x000b82, 0x000b82},
+ {0x000bc0, 0x000bc0},
+ {0x000bcd, 0x000bcd},
+ {0x000c00, 0x000c00},
+ {0x000c04, 0x000c04},
+ {0x000c3c, 0x000c3c},
+ {0x000c3e, 0x000c40},
+ {0x000c46, 0x000c48},
+ {0x000c4a, 0x000c4d},
+ {0x000c55, 0x000c56},
+ {0x000c62, 0x000c63},
+ {0x000c81, 0x000c81},
+ {0x000cbc, 0x000cbc},
+ {0x000cbf, 0x000cbf},
+ {0x000cc6, 0x000cc6},
+ {0x000ccc, 0x000ccd},
+ {0x000ce2, 0x000ce3},
+ {0x000d00, 0x000d01},
+ {0x000d3b, 0x000d3c},
+ {0x000d41, 0x000d44},
+ {0x000d4d, 0x000d4d},
+ {0x000d62, 0x000d63},
+ {0x000d81, 0x000d81},
+ {0x000dca, 0x000dca},
+ {0x000dd2, 0x000dd4},
+ {0x000dd6, 0x000dd6},
+ {0x000e31, 0x000e31},
+ {0x000e34, 0x000e3a},
+ {0x000e46, 0x000e46},
+ {0x000e47, 0x000e4e},
+ {0x000eb1, 0x000eb1},
+ {0x000eb4, 0x000ebc},
+ {0x000ec6, 0x000ec6},
+ {0x000ec8, 0x000ece},
+ {0x000f18, 0x000f19},
+ {0x000f35, 0x000f35},
+ {0x000f37, 0x000f37},
+ {0x000f39, 0x000f39},
+ {0x000f71, 0x000f7e},
+ {0x000f80, 0x000f84},
+ {0x000f86, 0x000f87},
+ {0x000f8d, 0x000f97},
+ {0x000f99, 0x000fbc},
+ {0x000fc6, 0x000fc6},
+ {0x00102d, 0x001030},
+ {0x001032, 0x001037},
+ {0x001039, 0x00103a},
+ {0x00103d, 0x00103e},
+ {0x001058, 0x001059},
+ {0x00105e, 0x001060},
+ {0x001071, 0x001074},
+ {0x001082, 0x001082},
+ {0x001085, 0x001086},
+ {0x00108d, 0x00108d},
+ {0x00109d, 0x00109d},
+ {0x0010fc, 0x0010fc},
+ {0x00135d, 0x00135f},
+ {0x001712, 0x001714},
+ {0x001732, 0x001733},
+ {0x001752, 0x001753},
+ {0x001772, 0x001773},
+ {0x0017b4, 0x0017b5},
+ {0x0017b7, 0x0017bd},
+ {0x0017c6, 0x0017c6},
+ {0x0017c9, 0x0017d3},
+ {0x0017d7, 0x0017d7},
+ {0x0017dd, 0x0017dd},
+ {0x00180b, 0x00180d},
+ {0x00180e, 0x00180e},
+ {0x00180f, 0x00180f},
+ {0x001843, 0x001843},
+ {0x001885, 0x001886},
+ {0x0018a9, 0x0018a9},
+ {0x001920, 0x001922},
+ {0x001927, 0x001928},
+ {0x001932, 0x001932},
+ {0x001939, 0x00193b},
+ {0x001a17, 0x001a18},
+ {0x001a1b, 0x001a1b},
+ {0x001a56, 0x001a56},
+ {0x001a58, 0x001a5e},
+ {0x001a60, 0x001a60},
+ {0x001a62, 0x001a62},
+ {0x001a65, 0x001a6c},
+ {0x001a73, 0x001a7c},
+ {0x001a7f, 0x001a7f},
+ {0x001aa7, 0x001aa7},
+ {0x001ab0, 0x001abd},
+ {0x001abe, 0x001abe},
+ {0x001abf, 0x001ace},
+ {0x001b00, 0x001b03},
+ {0x001b34, 0x001b34},
+ {0x001b36, 0x001b3a},
+ {0x001b3c, 0x001b3c},
+ {0x001b42, 0x001b42},
+ {0x001b6b, 0x001b73},
+ {0x001b80, 0x001b81},
+ {0x001ba2, 0x001ba5},
+ {0x001ba8, 0x001ba9},
+ {0x001bab, 0x001bad},
+ {0x001be6, 0x001be6},
+ {0x001be8, 0x001be9},
+ {0x001bed, 0x001bed},
+ {0x001bef, 0x001bf1},
+ {0x001c2c, 0x001c33},
+ {0x001c36, 0x001c37},
+ {0x001c78, 0x001c7d},
+ {0x001cd0, 0x001cd2},
+ {0x001cd4, 0x001ce0},
+ {0x001ce2, 0x001ce8},
+ {0x001ced, 0x001ced},
+ {0x001cf4, 0x001cf4},
+ {0x001cf8, 0x001cf9},
+ {0x001d2c, 0x001d6a},
+ {0x001d78, 0x001d78},
+ {0x001d9b, 0x001dbf},
+ {0x001dc0, 0x001dff},
+ {0x001fbd, 0x001fbd},
+ {0x001fbf, 0x001fc1},
+ {0x001fcd, 0x001fcf},
+ {0x001fdd, 0x001fdf},
+ {0x001fed, 0x001fef},
+ {0x001ffd, 0x001ffe},
+ {0x00200b, 0x00200f},
+ {0x002018, 0x002018},
+ {0x002019, 0x002019},
+ {0x002024, 0x002024},
+ {0x002027, 0x002027},
+ {0x00202a, 0x00202e},
+ {0x002060, 0x002064},
+ {0x002066, 0x00206f},
+ {0x002071, 0x002071},
+ {0x00207f, 0x00207f},
+ {0x002090, 0x00209c},
+ {0x0020d0, 0x0020dc},
+ {0x0020dd, 0x0020e0},
+ {0x0020e1, 0x0020e1},
+ {0x0020e2, 0x0020e4},
+ {0x0020e5, 0x0020f0},
+ {0x002c7c, 0x002c7d},
+ {0x002cef, 0x002cf1},
+ {0x002d6f, 0x002d6f},
+ {0x002d7f, 0x002d7f},
+ {0x002de0, 0x002dff},
+ {0x002e2f, 0x002e2f},
+ {0x003005, 0x003005},
+ {0x00302a, 0x00302d},
+ {0x003031, 0x003035},
+ {0x00303b, 0x00303b},
+ {0x003099, 0x00309a},
+ {0x00309b, 0x00309c},
+ {0x00309d, 0x00309e},
+ {0x0030fc, 0x0030fe},
+ {0x00a015, 0x00a015},
+ {0x00a4f8, 0x00a4fd},
+ {0x00a60c, 0x00a60c},
+ {0x00a66f, 0x00a66f},
+ {0x00a670, 0x00a672},
+ {0x00a674, 0x00a67d},
+ {0x00a67f, 0x00a67f},
+ {0x00a69c, 0x00a69d},
+ {0x00a69e, 0x00a69f},
+ {0x00a6f0, 0x00a6f1},
+ {0x00a700, 0x00a716},
+ {0x00a717, 0x00a71f},
+ {0x00a720, 0x00a721},
+ {0x00a770, 0x00a770},
+ {0x00a788, 0x00a788},
+ {0x00a789, 0x00a78a},
+ {0x00a7f2, 0x00a7f4},
+ {0x00a7f8, 0x00a7f9},
+ {0x00a802, 0x00a802},
+ {0x00a806, 0x00a806},
+ {0x00a80b, 0x00a80b},
+ {0x00a825, 0x00a826},
+ {0x00a82c, 0x00a82c},
+ {0x00a8c4, 0x00a8c5},
+ {0x00a8e0, 0x00a8f1},
+ {0x00a8ff, 0x00a8ff},
+ {0x00a926, 0x00a92d},
+ {0x00a947, 0x00a951},
+ {0x00a980, 0x00a982},
+ {0x00a9b3, 0x00a9b3},
+ {0x00a9b6, 0x00a9b9},
+ {0x00a9bc, 0x00a9bd},
+ {0x00a9cf, 0x00a9cf},
+ {0x00a9e5, 0x00a9e5},
+ {0x00a9e6, 0x00a9e6},
+ {0x00aa29, 0x00aa2e},
+ {0x00aa31, 0x00aa32},
+ {0x00aa35, 0x00aa36},
+ {0x00aa43, 0x00aa43},
+ {0x00aa4c, 0x00aa4c},
+ {0x00aa70, 0x00aa70},
+ {0x00aa7c, 0x00aa7c},
+ {0x00aab0, 0x00aab0},
+ {0x00aab2, 0x00aab4},
+ {0x00aab7, 0x00aab8},
+ {0x00aabe, 0x00aabf},
+ {0x00aac1, 0x00aac1},
+ {0x00aadd, 0x00aadd},
+ {0x00aaec, 0x00aaed},
+ {0x00aaf3, 0x00aaf4},
+ {0x00aaf6, 0x00aaf6},
+ {0x00ab5b, 0x00ab5b},
+ {0x00ab5c, 0x00ab5f},
+ {0x00ab69, 0x00ab69},
+ {0x00ab6a, 0x00ab6b},
+ {0x00abe5, 0x00abe5},
+ {0x00abe8, 0x00abe8},
+ {0x00abed, 0x00abed},
+ {0x00fb1e, 0x00fb1e},
+ {0x00fbb2, 0x00fbc2},
+ {0x00fe00, 0x00fe0f},
+ {0x00fe13, 0x00fe13},
+ {0x00fe20, 0x00fe2f},
+ {0x00fe52, 0x00fe52},
+ {0x00fe55, 0x00fe55},
+ {0x00feff, 0x00feff},
+ {0x00ff07, 0x00ff07},
+ {0x00ff0e, 0x00ff0e},
+ {0x00ff1a, 0x00ff1a},
+ {0x00ff3e, 0x00ff3e},
+ {0x00ff40, 0x00ff40},
+ {0x00ff70, 0x00ff70},
+ {0x00ff9e, 0x00ff9f},
+ {0x00ffe3, 0x00ffe3},
+ {0x00fff9, 0x00fffb},
+ {0x0101fd, 0x0101fd},
+ {0x0102e0, 0x0102e0},
+ {0x010376, 0x01037a},
+ {0x010780, 0x010785},
+ {0x010787, 0x0107b0},
+ {0x0107b2, 0x0107ba},
+ {0x010a01, 0x010a03},
+ {0x010a05, 0x010a06},
+ {0x010a0c, 0x010a0f},
+ {0x010a38, 0x010a3a},
+ {0x010a3f, 0x010a3f},
+ {0x010ae5, 0x010ae6},
+ {0x010d24, 0x010d27},
+ {0x010eab, 0x010eac},
+ {0x010efd, 0x010eff},
+ {0x010f46, 0x010f50},
+ {0x010f82, 0x010f85},
+ {0x011001, 0x011001},
+ {0x011038, 0x011046},
+ {0x011070, 0x011070},
+ {0x011073, 0x011074},
+ {0x01107f, 0x011081},
+ {0x0110b3, 0x0110b6},
+ {0x0110b9, 0x0110ba},
+ {0x0110bd, 0x0110bd},
+ {0x0110c2, 0x0110c2},
+ {0x0110cd, 0x0110cd},
+ {0x011100, 0x011102},
+ {0x011127, 0x01112b},
+ {0x01112d, 0x011134},
+ {0x011173, 0x011173},
+ {0x011180, 0x011181},
+ {0x0111b6, 0x0111be},
+ {0x0111c9, 0x0111cc},
+ {0x0111cf, 0x0111cf},
+ {0x01122f, 0x011231},
+ {0x011234, 0x011234},
+ {0x011236, 0x011237},
+ {0x01123e, 0x01123e},
+ {0x011241, 0x011241},
+ {0x0112df, 0x0112df},
+ {0x0112e3, 0x0112ea},
+ {0x011300, 0x011301},
+ {0x01133b, 0x01133c},
+ {0x011340, 0x011340},
+ {0x011366, 0x01136c},
+ {0x011370, 0x011374},
+ {0x011438, 0x01143f},
+ {0x011442, 0x011444},
+ {0x011446, 0x011446},
+ {0x01145e, 0x01145e},
+ {0x0114b3, 0x0114b8},
+ {0x0114ba, 0x0114ba},
+ {0x0114bf, 0x0114c0},
+ {0x0114c2, 0x0114c3},
+ {0x0115b2, 0x0115b5},
+ {0x0115bc, 0x0115bd},
+ {0x0115bf, 0x0115c0},
+ {0x0115dc, 0x0115dd},
+ {0x011633, 0x01163a},
+ {0x01163d, 0x01163d},
+ {0x01163f, 0x011640},
+ {0x0116ab, 0x0116ab},
+ {0x0116ad, 0x0116ad},
+ {0x0116b0, 0x0116b5},
+ {0x0116b7, 0x0116b7},
+ {0x01171d, 0x01171f},
+ {0x011722, 0x011725},
+ {0x011727, 0x01172b},
+ {0x01182f, 0x011837},
+ {0x011839, 0x01183a},
+ {0x01193b, 0x01193c},
+ {0x01193e, 0x01193e},
+ {0x011943, 0x011943},
+ {0x0119d4, 0x0119d7},
+ {0x0119da, 0x0119db},
+ {0x0119e0, 0x0119e0},
+ {0x011a01, 0x011a0a},
+ {0x011a33, 0x011a38},
+ {0x011a3b, 0x011a3e},
+ {0x011a47, 0x011a47},
+ {0x011a51, 0x011a56},
+ {0x011a59, 0x011a5b},
+ {0x011a8a, 0x011a96},
+ {0x011a98, 0x011a99},
+ {0x011c30, 0x011c36},
+ {0x011c38, 0x011c3d},
+ {0x011c3f, 0x011c3f},
+ {0x011c92, 0x011ca7},
+ {0x011caa, 0x011cb0},
+ {0x011cb2, 0x011cb3},
+ {0x011cb5, 0x011cb6},
+ {0x011d31, 0x011d36},
+ {0x011d3a, 0x011d3a},
+ {0x011d3c, 0x011d3d},
+ {0x011d3f, 0x011d45},
+ {0x011d47, 0x011d47},
+ {0x011d90, 0x011d91},
+ {0x011d95, 0x011d95},
+ {0x011d97, 0x011d97},
+ {0x011ef3, 0x011ef4},
+ {0x011f00, 0x011f01},
+ {0x011f36, 0x011f3a},
+ {0x011f40, 0x011f40},
+ {0x011f42, 0x011f42},
+ {0x013430, 0x01343f},
+ {0x013440, 0x013440},
+ {0x013447, 0x013455},
+ {0x016af0, 0x016af4},
+ {0x016b30, 0x016b36},
+ {0x016b40, 0x016b43},
+ {0x016f4f, 0x016f4f},
+ {0x016f8f, 0x016f92},
+ {0x016f93, 0x016f9f},
+ {0x016fe0, 0x016fe1},
+ {0x016fe3, 0x016fe3},
+ {0x016fe4, 0x016fe4},
+ {0x01aff0, 0x01aff3},
+ {0x01aff5, 0x01affb},
+ {0x01affd, 0x01affe},
+ {0x01bc9d, 0x01bc9e},
+ {0x01bca0, 0x01bca3},
+ {0x01cf00, 0x01cf2d},
+ {0x01cf30, 0x01cf46},
+ {0x01d167, 0x01d169},
+ {0x01d173, 0x01d17a},
+ {0x01d17b, 0x01d182},
+ {0x01d185, 0x01d18b},
+ {0x01d1aa, 0x01d1ad},
+ {0x01d242, 0x01d244},
+ {0x01da00, 0x01da36},
+ {0x01da3b, 0x01da6c},
+ {0x01da75, 0x01da75},
+ {0x01da84, 0x01da84},
+ {0x01da9b, 0x01da9f},
+ {0x01daa1, 0x01daaf},
+ {0x01e000, 0x01e006},
+ {0x01e008, 0x01e018},
+ {0x01e01b, 0x01e021},
+ {0x01e023, 0x01e024},
+ {0x01e026, 0x01e02a},
+ {0x01e030, 0x01e06d},
+ {0x01e08f, 0x01e08f},
+ {0x01e130, 0x01e136},
+ {0x01e137, 0x01e13d},
+ {0x01e2ae, 0x01e2ae},
+ {0x01e2ec, 0x01e2ef},
+ {0x01e4eb, 0x01e4eb},
+ {0x01e4ec, 0x01e4ef},
+ {0x01e8d0, 0x01e8d6},
+ {0x01e944, 0x01e94a},
+ {0x01e94b, 0x01e94b},
+ {0x01f3fb, 0x01f3ff},
+ {0x0e0001, 0x0e0001},
+ {0x0e0020, 0x0e007f},
+ {0x0e0100, 0x0e01ef},
+};
+
+/* table of Unicode codepoint ranges of White_Space characters */
+static const pg_unicode_range unicode_white_space[11] =
+{
+ {0x000009, 0x00000d},
+ {0x000020, 0x000020},
+ {0x000085, 0x000085},
+ {0x0000a0, 0x0000a0},
+ {0x001680, 0x001680},
+ {0x002000, 0x00200a},
+ {0x002028, 0x002028},
+ {0x002029, 0x002029},
+ {0x00202f, 0x00202f},
+ {0x00205f, 0x00205f},
+ {0x003000, 0x003000},
+};
+
+/* table of Unicode codepoint ranges of Hex_Digit characters */
+static const pg_unicode_range unicode_hex_digit[6] =
+{
+ {0x000030, 0x000039},
+ {0x000041, 0x000046},
+ {0x000061, 0x000066},
+ {0x00ff10, 0x00ff19},
+ {0x00ff21, 0x00ff26},
+ {0x00ff41, 0x00ff46},
+};
+
+/* table of Unicode codepoint ranges of Join_Control characters */
+static const pg_unicode_range unicode_join_control[1] =
+{
+ {0x00200c, 0x00200d},
};
--
2.34.1
[text/x-patch] v20-0002-Add-unicode-case-mapping-tables-and-functions.patch (317.3K, ../../[email protected]/3-v20-0002-Add-unicode-case-mapping-tables-and-functions.patch)
download | inline diff:
From abaf1b957fa462edf1e29a0722b00988738e195e Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 30 Oct 2023 17:38:54 -0700
Subject: [PATCH v20 2/6] Add unicode case mapping tables and functions.
---
src/common/Makefile | 1 +
src/common/meson.build | 1 +
src/common/unicode/Makefile | 15 +-
src/common/unicode/case_test.c | 100 +
.../unicode/generate-unicode_case_table.pl | 287 ++
src/common/unicode/meson.build | 33 +-
src/common/unicode_case.c | 398 +++
src/common/wchar.c | 4 +-
src/include/common/unicode_case.h | 33 +
src/include/common/unicode_case_table.h | 3183 +++++++++++++++++
src/include/mb/pg_wchar.h | 15 +
11 files changed, 4064 insertions(+), 6 deletions(-)
create mode 100644 src/common/unicode/case_test.c
create mode 100644 src/common/unicode/generate-unicode_case_table.pl
create mode 100644 src/common/unicode_case.c
create mode 100644 src/include/common/unicode_case.h
create mode 100644 src/include/common/unicode_case_table.h
diff --git a/src/common/Makefile b/src/common/Makefile
index 2ba5069dca..3d83299432 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -78,6 +78,7 @@ OBJS_COMMON = \
scram-common.o \
string.o \
stringinfo.o \
+ unicode_case.o \
unicode_category.o \
unicode_norm.o \
username.o \
diff --git a/src/common/meson.build b/src/common/meson.build
index 4eb16024cb..de68e408fa 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -32,6 +32,7 @@ common_sources = files(
'scram-common.c',
'string.c',
'stringinfo.c',
+ 'unicode_case.c',
'unicode_category.c',
'unicode_norm.c',
'username.c',
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index 27f0408d8b..6c3a275772 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -21,20 +21,24 @@ CPPFLAGS += $(ICU_CFLAGS)
# By default, do nothing.
all:
-update-unicode: unicode_category_table.h unicode_east_asian_fw_table.h unicode_nonspacing_table.h unicode_norm_hashfunc.h unicode_norm_table.h unicode_normprops_table.h unicode_version.h
+update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian_fw_table.h unicode_nonspacing_table.h unicode_norm_hashfunc.h unicode_norm_table.h unicode_normprops_table.h unicode_version.h
mv $^ $(top_srcdir)/src/include/common/
+ $(MAKE) case-check
$(MAKE) category-check
$(MAKE) normalization-check
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
$(PERL) $< --version $(UNICODE_VERSION)
+unicode_case_table.h: generate-unicode_case_table.pl UnicodeData.txt
+ $(PERL) $<
+
unicode_category_table.h: generate-unicode_category_table.pl DerivedCoreProperties.txt PropList.txt UnicodeData.txt
$(PERL) $<
@@ -55,12 +59,17 @@ unicode_normprops_table.h: generate-unicode_normprops_table.pl DerivedNormalizat
$(PERL) $^ >$@
# Test suite
+case-check: case_test
+ ./case_test
+
category-check: category_test
./category_test
normalization-check: norm_test
./norm_test
+case_test: case_test.o ../unicode_case.o | submake-common
+
category_test: category_test.o ../unicode_category.o | submake-common
norm_test: norm_test.o ../unicode_norm.o | submake-common
@@ -82,4 +91,4 @@ clean:
rm -f $(OBJS) category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/case_test.c b/src/common/unicode/case_test.c
new file mode 100644
index 0000000000..7b82d5e0aa
--- /dev/null
+++ b/src/common/unicode/case_test.c
@@ -0,0 +1,100 @@
+/*-------------------------------------------------------------------------
+ * case_test.c
+ * Program to test Unicode case mapping functions.
+ *
+ * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/unicode/case_test.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres_fe.h"
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wctype.h>
+
+#ifdef USE_ICU
+#include <unicode/uchar.h>
+#endif
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
+#include "common/unicode_version.h"
+
+#ifdef USE_ICU
+
+static void
+icu_test_simple(pg_wchar code)
+{
+ pg_wchar lower = unicode_lowercase_simple(code);
+ pg_wchar title = unicode_titlecase_simple(code);
+ pg_wchar upper = unicode_uppercase_simple(code);
+ pg_wchar iculower = u_tolower(code);
+ pg_wchar icutitle = u_totitle(code);
+ pg_wchar icuupper = u_toupper(code);
+
+ if (lower != iculower || title != icutitle || upper != icuupper)
+ {
+ printf("case_test: FAILURE for codepoint 0x%06x\n", code);
+ printf("case_test: Postgres lower/title/upper: 0x%06x/0x%06x/0x%06x\n",
+ lower, title, upper);
+ printf("case_test: ICU lower/title/upper: 0x%06x/0x%06x/0x%06x\n",
+ iculower, icutitle, icuupper);
+ printf("\n");
+ exit(1);
+ }
+}
+
+static void
+test_icu(void)
+{
+ int successful = 0;
+ int skipped_mismatch = 0;
+
+ for (pg_wchar code = 0; code <= 0x10ffff; code++)
+ {
+ pg_unicode_category category = unicode_category(code);
+
+ if (category != PG_U_UNASSIGNED)
+ {
+ uint8_t icu_category = u_charType(code);
+
+ if (icu_category == PG_U_UNASSIGNED)
+ {
+ skipped_mismatch++;
+ continue;
+ }
+
+ icu_test_simple(code);
+ successful++;
+ }
+ }
+
+ if (skipped_mismatch > 0)
+ printf("case_test: skipped %d codepoints unassigned in ICU due to Unicode version mismatch\n",
+ skipped_mismatch);
+
+ printf("case_test: ICU simple mapping test: %d codepoints successful\n",
+ successful);
+}
+#endif
+
+/*
+ * Exhaustively compare case mappings with the results from libc and ICU.
+ */
+int
+main(int argc, char **argv)
+{
+ printf("case_test: Postgres Unicode version:\t%s\n", PG_UNICODE_VERSION);
+#ifdef USE_ICU
+ printf("case_test: ICU Unicode version:\t\t%s\n", U_UNICODE_VERSION);
+ test_icu();
+#else
+ printf("case_test: ICU not available; skipping\n");
+#endif
+
+ exit(0);
+}
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
new file mode 100644
index 0000000000..02da4b682f
--- /dev/null
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -0,0 +1,287 @@
+#!/usr/bin/perl
+#
+# Generate Unicode character case mappings. Does not include tailoring
+# or locale-specific mappings.
+#
+# Input: SpecialCasing.txt UnicodeData.txt
+# Output: unicode_case_table.h
+#
+# Copyright (c) 2000-2023, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+use FindBin;
+use lib "$FindBin::RealBin/../../tools/";
+
+my $output_path = '.';
+
+GetOptions('outdir:s' => \$output_path);
+
+my $output_table_file = "$output_path/unicode_case_table.h";
+
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
+my $FH;
+
+my %simple = ();
+
+open($FH, '<', "$output_path/UnicodeData.txt")
+ or die "Could not open $output_path/UnicodeData.txt: $!.";
+while (my $line = <$FH>)
+{
+ my @elts = split(';', $line);
+ my $code = hex($elts[0]);
+ my $simple_uppercase = hex($elts[12] =~ s/^\s+|\s+$//rg);
+ my $simple_lowercase = hex($elts[13] =~ s/^\s+|\s+$//rg);
+ my $simple_titlecase = hex($elts[14] =~ s/^\s+|\s+$//rg);
+
+ die "codepoint $code out of range" if $code > 0x10FFFF;
+ die "Simple_Lowercase $code out of range" if $simple_lowercase > 0x10FFFF;
+ die "Simple_Titlecase $code out of range" if $simple_titlecase > 0x10FFFF;
+ die "Simple_Uppercase $code out of range" if $simple_uppercase > 0x10FFFF;
+
+ if ($simple_lowercase || $simple_titlecase || $simple_uppercase)
+ {
+ $simple{$code} = {
+ Simple_Lowercase => ($simple_lowercase || $code),
+ Simple_Titlecase => ($simple_titlecase || $code),
+ Simple_Uppercase => ($simple_uppercase || $code)
+ };
+ }
+}
+close $FH;
+
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
+# Start writing out the output files
+open my $OT, '>', $output_table_file
+ or die "Could not open output file $output_table_file: $!\n";
+
+# determine size of array given that codepoints <= 0x80 are dense and
+# the rest of the entries are sparse
+my $num_simple = 0x80;
+foreach my $code (sort { $a <=> $b } (keys %simple))
+{
+ $num_simple++ unless $code < 0x80;
+}
+
+my $num_special = scalar(keys %special) + 1;
+
+print $OT <<"EOS";
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case_table.h
+ * Case mapping and information table.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/common/unicode_case_table.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * File auto-generated by src/common/unicode/generate-unicode_case_table.pl,
+ * do not edit. There is deliberately not an #ifndef PG_UNICODE_CASE_TABLE_H
+ * here.
+ */
+
+#include "common/unicode_case.h"
+#include "mb/pg_wchar.h"
+
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
+typedef enum
+{
+ CaseLower = 0,
+ CaseTitle = 1,
+ CaseUpper = 2,
+ NCaseKind
+} CaseKind;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
+} pg_case_map;
+
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
+/*
+ * Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
+ * sparse for higher codepoints (requiring scan or binary search).
+ */
+static const pg_case_map case_map[$num_simple] =
+{
+EOS
+
+printf $OT "\t/* begin dense entries for codepoints < 0x80 */\n";
+for (my $code = 0; $code < 0x80; $code++)
+{
+ my $lc = ($simple{$code}{Simple_Lowercase} || $code);
+ my $tc = ($simple{$code}{Simple_Titlecase} || $code);
+ my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
+ printf $OT
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
+ $code, $lc, $tc, $uc;
+}
+printf $OT "\n";
+
+printf $OT "\t/* begin sparse entries for codepoints >= 0x80 */\n";
+foreach my $code (sort { $a <=> $b } (keys %simple))
+{
+ next unless $code >= 0x80; # already output above
+
+ my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
+ printf $OT
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
+ $code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
+ $map->{Simple_Uppercase}, $special_case;
+}
+print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index d7190bb8ca..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -24,6 +24,16 @@ endforeach
update_unicode_targets = []
+update_unicode_targets += \
+ custom_target('unicode_case_table.h',
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
+ output: ['unicode_case_table.h'],
+ command: [
+ perl, files('generate-unicode_case_table.pl'),
+ '--outdir', '@OUTDIR@', '@INPUT@'],
+ build_by_default: false,
+ )
+
update_unicode_targets += \
custom_target('unicode_category_table.h',
input: [unicode_data['UnicodeData.txt'], unicode_data['DerivedCoreProperties.txt'], unicode_data['PropList.txt']],
@@ -92,6 +102,17 @@ norm_test_table = custom_target('norm_test_table.h',
inc = include_directories('.')
+case_test = executable('case_test',
+ ['case_test.c'],
+ dependencies: [frontend_port_code, icu],
+ include_directories: inc,
+ link_with: [common_static, pgport_static],
+ build_by_default: false,
+ kwargs: default_bin_args + {
+ 'install': false,
+ }
+)
+
category_test = executable('category_test',
['category_test.c'],
dependencies: [frontend_port_code, icu],
@@ -116,6 +137,16 @@ norm_test = executable('norm_test',
update_unicode_dep = []
+if not meson.is_cross_build()
+ update_unicode_dep += custom_target('case_test.run',
+ output: 'case_test.run',
+ input: update_unicode_targets,
+ command: [case_test, UNICODE_VERSION],
+ build_by_default: false,
+ build_always_stale: true,
+ )
+endif
+
if not meson.is_cross_build()
update_unicode_dep += custom_target('category_test.run',
output: 'category_test.run',
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
new file mode 100644
index 0000000000..b1e6bf3208
--- /dev/null
+++ b/src/common/unicode_case.c
@@ -0,0 +1,398 @@
+/*-------------------------------------------------------------------------
+ * unicode_case.c
+ * Conversion to upper or lower case.
+ *
+ * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/unicode_case.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/unicode_case.h"
+#include "common/unicode_case_table.h"
+#include "common/unicode_category.h"
+#include "mb/pg_wchar.h"
+
+static const pg_case_map *find_case_map(pg_wchar ucs);
+static size_t convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
+ CaseKind top_casekind, bool real_titlecase,
+ bool adjust_to_cased, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
+
+pg_wchar
+unicode_lowercase_simple(pg_wchar code)
+{
+ const pg_case_map *map = find_case_map(code);
+
+ return map ? map->simplemap[CaseLower] : code;
+}
+
+pg_wchar
+unicode_titlecase_simple(pg_wchar code)
+{
+ const pg_case_map *map = find_case_map(code);
+
+ return map ? map->simplemap[CaseTitle] : code;
+}
+
+pg_wchar
+unicode_uppercase_simple(pg_wchar code)
+{
+ const pg_case_map *map = find_case_map(code);
+
+ return map ? map->simplemap[CaseUpper] : code;
+}
+
+/*
+ * unicode_strlower()
+ *
+ * Convert src to lowercase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
+ */
+size_t
+unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool full)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseLower, false, false,
+ full, NULL, NULL);
+}
+
+/*
+ * unicode_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
+ *
+ * Titlecasing requires knowledge about word boundaries, which is provided by
+ * the callback wbnext. A word boundary is the offset of the start of a word
+ * or the offset of the character immediately following a word.
+ *
+ * The caller is expected to initialize and free the callback state
+ * wbstate. The callback should first return offset 0 for the first boundary;
+ * then the offset of each subsequent word boundary; then the total length of
+ * the string to indicate the final boundary.
+ *
+ * If real_titlecase is true, use CaseTitle and CaseLower mappings; otherwise
+ * use CaseUpper and CaseLower mappings.
+ *
+ * If adjust_to_cased is true, adjusts to next Cased character after a word
+ * boundary before titlecasing (Default Case Conversion algorithm). Otherwise,
+ * titlecases the character at the word boundary without adjustment (if a
+ * mapping is available).
+ */
+size_t
+unicode_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool real_titlecase, bool adjust_to_cased, bool full,
+ WordBoundaryNext wbnext, void *wbstate)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, real_titlecase,
+ adjust_to_cased, full, wbnext, wbstate);
+}
+
+/*
+ * unicode_strupper()
+ *
+ * Convert src to uppercase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
+ */
+size_t
+unicode_strupper(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool full)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, false, false,
+ full, NULL, NULL);
+}
+
+/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
+ * If str_casekind is CaseLower or CaseUpper, map each character in the string
+ * for which a mapping is available.
+ *
+ * If str_casekind is CaseTitle: for each word boundary, "adjust" forward to
+ * the next Cased character and map it to titlecase; then map subsequent
+ * characters to lowercase until the next word boundary.
+ *
+ * Some characters have special mappings, which can map a single codepoint to
+ * multiple codepoints, or depend on conditions.
+ */
+static size_t
+convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
+ CaseKind str_casekind, bool real_titlecase, bool adjust_to_cased,
+ bool full, WordBoundaryNext wbnext, void *wbstate)
+{
+ /* character CaseKind varies while titlecasing */
+ CaseKind chr_casekind = str_casekind;
+ size_t srcoff = 0;
+ size_t result_len = 0;
+ size_t boundary = 0;
+ bool adjusting = true;
+
+ Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
+ (str_casekind != CaseTitle && !wbnext && !wbstate &&
+ !real_titlecase && !adjust_to_cased));
+
+ if (str_casekind == CaseTitle)
+ {
+ boundary = wbnext(wbstate);
+ Assert(boundary == 0); /* start of text is always a boundary */
+ }
+
+ while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
+ {
+ pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
+ int u1len = unicode_utf8len(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+
+ /*
+ * Titlecasing has two states: adjusting from boundary (initial
+ * state), and lowercasing until the next boundary.
+ */
+ if (str_casekind == CaseTitle)
+ {
+ if (srcoff == boundary)
+ {
+ /* reset to initial state and find the next boundary */
+ adjusting = true;
+ boundary = wbnext(wbstate);
+ }
+
+ if (adjusting)
+ {
+ if (!adjust_to_cased || pg_u_prop_cased(u1))
+ {
+ /* adjustment done: map to titlecase */
+ adjusting = false;
+ chr_casekind = real_titlecase ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else
+ casemap = NULL; /* no mapping during adjustment */
+ }
+ else
+ {
+ chr_casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Note: only a single special mapping per codepoint is currently
+ * supported, though Unicode allows for multiple special mappings for
+ * a single codepoint.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[chr_casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
+ {
+ pg_wchar u2 = casemap->simplemap[chr_casekind];
+ pg_wchar u2len = unicode_utf8len(u2);
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ else
+ {
+ /* no mapping; copy bytes from src */
+ if (result_len + u1len < dstsize)
+ memcpy(dst + result_len, src + srcoff, u1len);
+
+ result_len += u1len;
+ }
+
+ srcoff += u1len;
+ }
+
+ if (result_len < dstsize)
+ dst[result_len] = '\0';
+
+ return result_len;
+}
+
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
+/* find entry in simple case map, if any */
+static const pg_case_map *
+find_case_map(pg_wchar ucs)
+{
+ int min = 0;
+ int mid;
+ int max = lengthof(case_map) - 1;
+
+ /* all chars <= 0x80 are stored in array for fast lookup */
+ Assert(max >= 0x7f);
+ if (ucs < 0x80)
+ {
+ const pg_case_map *map = &case_map[ucs];
+
+ Assert(map->codepoint == ucs);
+ return map;
+ }
+
+ /* otherwise, binary search */
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (ucs > case_map[mid].codepoint)
+ min = mid + 1;
+ else if (ucs < case_map[mid].codepoint)
+ max = mid - 1;
+ else
+ return &case_map[mid];
+ }
+
+ return NULL;
+}
diff --git a/src/common/wchar.c b/src/common/wchar.c
index 7e7a7507d5..a238c0106c 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -477,8 +477,8 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
/*
- * Map a Unicode code point to UTF-8. utf8string must have 4 bytes of
- * space allocated.
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
*/
unsigned char *
unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
new file mode 100644
index 0000000000..75445441f4
--- /dev/null
+++ b/src/include/common/unicode_case.h
@@ -0,0 +1,33 @@
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case.h
+ * Routines for converting character case.
+ *
+ * These definitions can be used by both frontend and backend code.
+ *
+ * Copyright (c) 2017-2023, PostgreSQL Global Development Group
+ *
+ * src/include/common/unicode_case.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef UNICODE_CASE_H
+#define UNICODE_CASE_H
+
+#include "mb/pg_wchar.h"
+
+typedef size_t (*WordBoundaryNext) (void *wbstate);
+
+pg_wchar unicode_lowercase_simple(pg_wchar ucs);
+pg_wchar unicode_titlecase_simple(pg_wchar ucs);
+pg_wchar unicode_uppercase_simple(pg_wchar ucs);
+size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
+ size_t srclen, bool full);
+size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
+ size_t srclen, bool real_titlecase,
+ bool adjust_to_cased, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
+size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
+ size_t srclen, bool full);
+
+#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
new file mode 100644
index 0000000000..081d4133b1
--- /dev/null
+++ b/src/include/common/unicode_case_table.h
@@ -0,0 +1,3183 @@
+/*-------------------------------------------------------------------------
+ *
+ * unicode_case_table.h
+ * Case mapping and information table.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/common/unicode_case_table.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * File auto-generated by src/common/unicode/generate-unicode_case_table.pl,
+ * do not edit. There is deliberately not an #ifndef PG_UNICODE_CASE_TABLE_H
+ * here.
+ */
+
+#include "common/unicode_case.h"
+#include "mb/pg_wchar.h"
+
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
+typedef enum
+{
+ CaseLower = 0,
+ CaseTitle = 1,
+ CaseUpper = 2,
+ NCaseKind
+} CaseKind;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
+} pg_case_map;
+
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
+/*
+ * Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
+ * sparse for higher codepoints (requiring scan or binary search).
+ */
+static const pg_case_map case_map[3003] =
+{
+ /* begin dense entries for codepoints < 0x80 */
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
+
+ /* begin sparse entries for codepoints >= 0x80 */
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+};
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 32e25a1a6e..69a55b66f4 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -555,6 +555,21 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Number of bytes needed to represent the given char in UTF8.
+ */
+static inline int
+unicode_utf8len(pg_wchar c)
+{
+ if (c <= 0x7F)
+ return 1;
+ else if (c <= 0x7FF)
+ return 2;
+ else if (c <= 0xFFFF)
+ return 3;
+ else
+ return 4;
+}
/*
* The functions in this list are exported by libpq, and we need to be sure
--
2.34.1
[text/x-patch] v20-0003-Catalog-changes-preparing-for-builtin-collation-.patch (48.5K, ../../[email protected]/4-v20-0003-Catalog-changes-preparing-for-builtin-collation-.patch)
download | inline diff:
From 7b325c5f5e2e1799e498288cff1589cc247f9534 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Tue, 26 Dec 2023 13:32:48 -0800
Subject: [PATCH v20 3/6] Catalog changes preparing for builtin collation
provider.
daticulocale -> datlocale, colliculocale -> colllocale.
---
doc/src/sgml/bki.sgml | 2 +-
doc/src/sgml/catalogs.sgml | 8 +--
src/backend/catalog/pg_collation.c | 10 +--
src/backend/commands/collationcmds.c | 34 +++++-----
src/backend/commands/dbcommands.c | 68 +++++++++----------
src/backend/utils/adt/pg_locale.c | 4 +-
src/backend/utils/init/postinit.c | 12 ++--
src/bin/initdb/initdb.c | 32 ++++-----
src/bin/pg_dump/pg_dump.c | 56 ++++++++-------
src/bin/pg_upgrade/info.c | 31 ++++++---
src/bin/pg_upgrade/pg_upgrade.c | 34 +++++++---
src/bin/pg_upgrade/pg_upgrade.h | 2 +-
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 27 +++++---
src/bin/psql/describe.c | 20 ++++--
src/include/catalog/pg_collation.dat | 2 +-
src/include/catalog/pg_collation.h | 4 +-
src/include/catalog/pg_database.dat | 2 +-
src/include/catalog/pg_database.h | 2 +-
.../regress/expected/collate.icu.utf8.out | 4 +-
src/test/regress/expected/psql.out | 18 ++---
src/test/regress/sql/collate.icu.utf8.sql | 4 +-
21 files changed, 211 insertions(+), 165 deletions(-)
diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 315ba81951..3cd5bee7ff 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -186,7 +186,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE', datacl => '_null_' },
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE', datacl => '_null_' },
]
]]></programlisting>
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 880f717b10..734b1cf74f 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2422,10 +2422,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>colliculocale</structfield> <type>text</type>
+ <structfield>colllocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this collation object
+ Locale name for builtin or ICU provider
</para></entry>
</row>
@@ -3131,10 +3131,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>daticulocale</structfield> <type>text</type>
+ <structfield>datlocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this database
+ Locale name for builtin or ICU provider
</para></entry>
</row>
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 5c8ccb8b3b..7bad94f908 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -49,7 +49,7 @@ CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
@@ -68,7 +68,7 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colliculocale);
+ Assert((collcollate && collctype) || colllocale);
/*
* Make sure there is no existing collation of same name & encoding.
@@ -191,10 +191,10 @@ CollationCreate(const char *collname, Oid collnamespace,
values[Anum_pg_collation_collctype - 1] = CStringGetTextDatum(collctype);
else
nulls[Anum_pg_collation_collctype - 1] = true;
- if (colliculocale)
- values[Anum_pg_collation_colliculocale - 1] = CStringGetTextDatum(colliculocale);
+ if (colllocale)
+ values[Anum_pg_collation_colllocale - 1] = CStringGetTextDatum(colllocale);
else
- nulls[Anum_pg_collation_colliculocale - 1] = true;
+ nulls[Anum_pg_collation_colllocale - 1] = true;
if (collicurules)
values[Anum_pg_collation_collicurules - 1] = CStringGetTextDatum(collicurules);
else
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 58c059fdb7..27564e569a 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -68,7 +68,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colliculocale;
+ char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -159,11 +159,11 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
else
collctype = NULL;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colliculocale, &isnull);
+ datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colllocale, &isnull);
if (!isnull)
- colliculocale = TextDatumGetCString(datum);
+ colllocale = TextDatumGetCString(datum);
else
- colliculocale = NULL;
+ colllocale = NULL;
/*
* When the ICU locale comes from an existing collation, do not
@@ -196,7 +196,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collcollate = NULL;
collctype = NULL;
- colliculocale = NULL;
+ colllocale = NULL;
collicurules = NULL;
if (providerEl)
@@ -236,7 +236,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collctype = defGetString(localeEl);
}
else
- colliculocale = defGetString(localeEl);
+ colllocale = defGetString(localeEl);
}
if (lccollateEl)
@@ -261,7 +261,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
else if (collprovider == COLLPROVIDER_ICU)
{
- if (!colliculocale)
+ if (!colllocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("parameter \"%s\" must be specified",
@@ -273,20 +273,20 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
*/
if (!IsBinaryUpgrade)
{
- char *langtag = icu_language_tag(colliculocale,
+ char *langtag = icu_language_tag(colllocale,
icu_validation_level);
- if (langtag && strcmp(colliculocale, langtag) != 0)
+ if (langtag && strcmp(colllocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, colliculocale)));
+ langtag, colllocale)));
- colliculocale = langtag;
+ colllocale = langtag;
}
}
- icu_validate_locale(colliculocale);
+ icu_validate_locale(colllocale);
}
/*
@@ -334,7 +334,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colliculocale : collcollate);
+ collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
newoid = CollationCreate(collName,
collNamespace,
@@ -344,7 +344,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collencoding,
collcollate,
collctype,
- colliculocale,
+ colllocale,
collicurules,
collversion,
if_not_exists,
@@ -435,7 +435,7 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
/* cannot change from NULL to non-NULL or vice versa */
@@ -502,7 +502,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
provider == COLLPROVIDER_ICU ?
- Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ Anum_pg_database_datlocale : Anum_pg_database_datcollate);
locale = TextDatumGetCString(datum);
@@ -523,7 +523,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
Assert(provider != COLLPROVIDER_DEFAULT);
datum = SysCacheGetAttrNotNull(COLLOID, colltp,
provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
locale = TextDatumGetCString(datum);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index b1327de71e..d1de46e759 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -118,7 +118,7 @@ static bool get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion);
@@ -675,7 +675,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
int src_encoding = -1;
char *src_collate = NULL;
char *src_ctype = NULL;
- char *src_iculocale = NULL;
+ char *src_locale = NULL;
char *src_icurules = NULL;
char src_locprovider = '\0';
char *src_collversion = NULL;
@@ -713,7 +713,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dbiculocale = NULL;
+ char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -903,7 +903,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (dctype && dctype->arg)
dbctype = defGetString(dctype);
if (diculocale && diculocale->arg)
- dbiculocale = defGetString(diculocale);
+ dblocale = defGetString(diculocale);
if (dicurules && dicurules->arg)
dbicurules = defGetString(dicurules);
if (dlocprovider && dlocprovider->arg)
@@ -971,7 +971,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
&src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_allowconn, &src_hasloginevt,
&src_frozenxid, &src_minmxid, &src_deftablespace,
- &src_collate, &src_ctype, &src_iculocale, &src_icurules, &src_locprovider,
+ &src_collate, &src_ctype, &src_locale, &src_icurules, &src_locprovider,
&src_collversion))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
@@ -1027,12 +1027,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dbiculocale == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
{
if (dlocale && dlocale->arg)
- dbiculocale = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
else
- dbiculocale = src_iculocale;
+ dblocale = src_locale;
}
if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
dbicurules = src_icurules;
@@ -1071,7 +1071,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* This would happen if template0 uses the libc provider but the new
* database uses icu.
*/
- if (!dbiculocale)
+ if (!dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALE or ICU_LOCALE must be specified")));
@@ -1081,26 +1081,26 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* database, preserve locale string. Otherwise, canonicalize to a
* language tag.
*/
- if (!IsBinaryUpgrade && dbiculocale != src_iculocale)
+ if (!IsBinaryUpgrade && dblocale != src_locale)
{
- char *langtag = icu_language_tag(dbiculocale,
+ char *langtag = icu_language_tag(dblocale,
icu_validation_level);
- if (langtag && strcmp(dbiculocale, langtag) != 0)
+ if (langtag && strcmp(dblocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, dbiculocale)));
+ langtag, dblocale)));
- dbiculocale = langtag;
+ dblocale = langtag;
}
}
- icu_validate_locale(dbiculocale);
+ icu_validate_locale(dblocale);
}
else
{
- if (dbiculocale)
+ if (dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1157,13 +1157,13 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
char *val1;
char *val2;
- Assert(dbiculocale);
- Assert(src_iculocale);
- if (strcmp(dbiculocale, src_iculocale) != 0)
+ Assert(dblocale);
+ Assert(src_locale);
+ if (strcmp(dblocale, src_locale) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("new ICU locale (%s) is incompatible with the ICU locale of the template database (%s)",
- dbiculocale, src_iculocale),
+ dblocale, src_locale),
errhint("Use the same ICU locale as in the template database, or use template0 as template.")));
val1 = dbicurules;
@@ -1197,7 +1197,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *actual_versionstr;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1225,7 +1225,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1364,8 +1364,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dbiculocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dbiculocale));
+ Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
+ (dblocprovider != COLLPROVIDER_ICU && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -1383,10 +1383,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);
new_record[Anum_pg_database_datcollate - 1] = CStringGetTextDatum(dbcollate);
new_record[Anum_pg_database_datctype - 1] = CStringGetTextDatum(dbctype);
- if (dbiculocale)
- new_record[Anum_pg_database_daticulocale - 1] = CStringGetTextDatum(dbiculocale);
+ if (dblocale)
+ new_record[Anum_pg_database_datlocale - 1] = CStringGetTextDatum(dblocale);
else
- new_record_nulls[Anum_pg_database_daticulocale - 1] = true;
+ new_record_nulls[Anum_pg_database_datlocale - 1] = true;
if (dbicurules)
new_record[Anum_pg_database_daticurules - 1] = CStringGetTextDatum(dbicurules);
else
@@ -2472,7 +2472,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
if (isnull)
elog(ERROR, "unexpected null in pg_database");
newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
@@ -2670,7 +2670,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
ReleaseSysCache(tp);
@@ -2697,7 +2697,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion)
@@ -2808,13 +2808,13 @@ get_db_info(const char *name, LOCKMODE lockmode,
datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datctype);
*dbCtype = TextDatumGetCString(datum);
}
- if (dbIculocale)
+ if (dbLocale)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_daticulocale, &isnull);
+ datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datlocale, &isnull);
if (isnull)
- *dbIculocale = NULL;
+ *dbLocale = NULL;
else
- *dbIculocale = TextDatumGetCString(datum);
+ *dbLocale = TextDatumGetCString(datum);
}
if (dbIcurules)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 79b59b0af7..45fe847320 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1606,7 +1606,7 @@ pg_newlocale_from_collation(Oid collid)
const char *iculocstr;
const char *icurules;
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colliculocale);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
iculocstr = TextDatumGetCString(datum);
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
@@ -1627,7 +1627,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
TextDatumGetCString(datum));
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5ffe9bdd98..154912ecb4 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -320,7 +320,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
bool isnull;
char *collate;
char *ctype;
- char *iculocale;
+ char *datlocale;
/* Fetch our pg_database row normally, via syscache */
tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
@@ -429,8 +429,8 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *icurules;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_daticulocale);
- iculocale = TextDatumGetCString(datum);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
if (!isnull)
@@ -438,10 +438,10 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
else
icurules = NULL;
- make_icu_collator(iculocale, icurules, &default_locale);
+ make_icu_collator(datlocale, icurules, &default_locale);
}
else
- iculocale = NULL;
+ datlocale = NULL;
default_locale.provider = dbform->datlocprovider;
@@ -466,7 +466,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? iculocale : collate);
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ac409b0006..90f793632a 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -145,7 +145,7 @@ static char *lc_numeric = NULL;
static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
-static char *icu_locale = NULL;
+static char *datlocale = NULL;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -1515,8 +1515,8 @@ bootstrap_template1(void)
bki_lines = replace_token(bki_lines, "LC_CTYPE",
escape_quotes_bki(lc_ctype));
- bki_lines = replace_token(bki_lines, "ICU_LOCALE",
- icu_locale ? escape_quotes_bki(icu_locale) : "_null_");
+ bki_lines = replace_token(bki_lines, "DATLOCALE",
+ datlocale ? escape_quotes_bki(datlocale) : "_null_");
bki_lines = replace_token(bki_lines, "ICU_RULES",
icu_rules ? escape_quotes_bki(icu_rules) : "_null_");
@@ -2363,8 +2363,8 @@ setlocales(void)
lc_monetary = locale;
if (!lc_messages)
lc_messages = locale;
- if (!icu_locale && locale_provider == COLLPROVIDER_ICU)
- icu_locale = locale;
+ if (!datlocale && locale_provider != COLLPROVIDER_LIBC)
+ datlocale = locale;
}
/*
@@ -2395,17 +2395,17 @@ setlocales(void)
char *langtag;
/* acquire default locale from the environment, if not specified */
- if (icu_locale == NULL)
+ if (datlocale == NULL)
pg_fatal("ICU locale must be specified");
/* canonicalize to a language tag */
- langtag = icu_language_tag(icu_locale);
+ langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
- langtag, icu_locale);
- pg_free(icu_locale);
- icu_locale = langtag;
+ langtag, datlocale);
+ pg_free(datlocale);
+ datlocale = langtag;
- icu_validate_locale(icu_locale);
+ icu_validate_locale(datlocale);
/*
* In supported builds, the ICU locale ID will be opened during
@@ -2599,14 +2599,14 @@ setup_locale_encoding(void)
strcmp(lc_ctype, lc_numeric) == 0 &&
strcmp(lc_ctype, lc_monetary) == 0 &&
strcmp(lc_ctype, lc_messages) == 0 &&
- (!icu_locale || strcmp(lc_ctype, icu_locale) == 0))
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (icu_locale)
- printf(_(" ICU locale: %s\n"), icu_locale);
+ if (datlocale)
+ printf(_(" ICU locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3277,7 +3277,7 @@ main(int argc, char *argv[])
pg_fatal("unrecognized locale provider: %s", optarg);
break;
case 16:
- icu_locale = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
break;
case 17:
icu_rules = pg_strdup(optarg);
@@ -3312,7 +3312,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (icu_locale && locale_provider != COLLPROVIDER_ICU)
+ if (datlocale && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 2225a12718..a67b4b8225 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2984,7 +2984,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider,
i_collate,
i_ctype,
- i_daticulocale,
+ i_datlocale,
i_daticurules,
i_frozenxid,
i_minmxid,
@@ -3003,7 +3003,7 @@ dumpDatabase(Archive *fout)
*datlocprovider,
*collate,
*ctype,
- *iculocale,
+ *locale,
*icurules,
*datistemplate,
*datconnlimit,
@@ -3027,10 +3027,12 @@ dumpDatabase(Archive *fout)
appendPQExpBufferStr(dbQry, "datminmxid, ");
else
appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
- if (fout->remoteVersion >= 150000)
- appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale, datcollversion, ");
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
+ else if (fout->remoteVersion >= 150000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
else
- appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS daticulocale, NULL AS datcollversion, ");
+ appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(dbQry, "daticurules, ");
else
@@ -3051,7 +3053,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider = PQfnumber(res, "datlocprovider");
i_collate = PQfnumber(res, "datcollate");
i_ctype = PQfnumber(res, "datctype");
- i_daticulocale = PQfnumber(res, "daticulocale");
+ i_datlocale = PQfnumber(res, "datlocale");
i_daticurules = PQfnumber(res, "daticurules");
i_frozenxid = PQfnumber(res, "datfrozenxid");
i_minmxid = PQfnumber(res, "datminmxid");
@@ -3070,10 +3072,10 @@ dumpDatabase(Archive *fout)
datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
collate = PQgetvalue(res, 0, i_collate);
ctype = PQgetvalue(res, 0, i_ctype);
- if (!PQgetisnull(res, 0, i_daticulocale))
- iculocale = PQgetvalue(res, 0, i_daticulocale);
+ if (!PQgetisnull(res, 0, i_datlocale))
+ locale = PQgetvalue(res, 0, i_datlocale);
else
- iculocale = NULL;
+ locale = NULL;
if (!PQgetisnull(res, 0, i_daticurules))
icurules = PQgetvalue(res, 0, i_daticurules);
else
@@ -3138,11 +3140,12 @@ dumpDatabase(Archive *fout)
appendStringLiteralAH(creaQry, ctype, fout);
}
}
- if (iculocale)
+ if (locale)
{
appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
- appendStringLiteralAH(creaQry, iculocale, fout);
+ appendStringLiteralAH(creaQry, locale, fout);
}
+
if (icurules)
{
appendPQExpBufferStr(creaQry, " ICU_RULES = ");
@@ -13756,12 +13759,12 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
int i_collisdeterministic;
int i_collcollate;
int i_collctype;
- int i_colliculocale;
+ int i_colllocale;
int i_collicurules;
const char *collprovider;
const char *collcollate;
const char *collctype;
- const char *colliculocale;
+ const char *colllocale;
const char *collicurules;
/* Do nothing in data-only dump */
@@ -13793,12 +13796,15 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
appendPQExpBufferStr(query,
"true AS collisdeterministic, ");
- if (fout->remoteVersion >= 150000)
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(query,
+ "colllocale, ");
+ else if (fout->remoteVersion >= 150000)
appendPQExpBufferStr(query,
- "colliculocale, ");
+ "colliculocale AS colllocale, ");
else
appendPQExpBufferStr(query,
- "NULL AS colliculocale, ");
+ "NULL AS colllocale, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(query,
@@ -13820,7 +13826,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
i_collisdeterministic = PQfnumber(res, "collisdeterministic");
i_collcollate = PQfnumber(res, "collcollate");
i_collctype = PQfnumber(res, "collctype");
- i_colliculocale = PQfnumber(res, "colliculocale");
+ i_colllocale = PQfnumber(res, "colllocale");
i_collicurules = PQfnumber(res, "collicurules");
collprovider = PQgetvalue(res, 0, i_collprovider);
@@ -13847,10 +13853,10 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
collctype = NULL;
}
- if (!PQgetisnull(res, 0, i_colliculocale))
- colliculocale = PQgetvalue(res, 0, i_colliculocale);
+ if (!PQgetisnull(res, 0, i_colllocale))
+ colllocale = PQgetvalue(res, 0, i_colllocale);
else
- colliculocale = NULL;
+ colllocale = NULL;
if (!PQgetisnull(res, 0, i_collicurules))
collicurules = PQgetvalue(res, 0, i_collicurules);
@@ -13880,7 +13886,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
if (collprovider[0] == 'd')
{
- if (collcollate || collctype || colliculocale || collicurules)
+ if (collcollate || collctype || colllocale || collicurules)
pg_log_warning("invalid collation \"%s\"", qcollname);
/* no locale -- the default collation cannot be reloaded anyway */
@@ -13889,16 +13895,16 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
{
if (fout->remoteVersion >= 150000)
{
- if (collcollate || collctype || !colliculocale)
+ if (collcollate || collctype || !colllocale)
pg_log_warning("invalid collation \"%s\"", qcollname);
appendPQExpBufferStr(q, ", locale = ");
- appendStringLiteralAH(q, colliculocale ? colliculocale : "",
+ appendStringLiteralAH(q, colllocale ? colllocale : "",
fout);
}
else
{
- if (!collcollate || !collctype || colliculocale ||
+ if (!collcollate || !collctype || colllocale ||
strcmp(collcollate, collctype) != 0)
pg_log_warning("invalid collation \"%s\"", qcollname);
@@ -13914,7 +13920,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
}
else if (collprovider[0] == 'c')
{
- if (colliculocale || collicurules || !collcollate || !collctype)
+ if (colllocale || collicurules || !collcollate || !collctype)
pg_log_warning("invalid collation \"%s\"", qcollname);
if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c
index 183c2f84eb..101fe855fc 100644
--- a/src/bin/pg_upgrade/info.c
+++ b/src/bin/pg_upgrade/info.c
@@ -328,18 +328,24 @@ get_template0_info(ClusterInfo *cluster)
int i_datlocprovider;
int i_datcollate;
int i_datctype;
- int i_daticulocale;
+ int i_datlocale;
- if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
dbres = executeQueryOrDie(conn,
"SELECT encoding, datlocprovider, "
- " datcollate, datctype, daticulocale "
+ " datcollate, datctype, datlocale "
+ "FROM pg_catalog.pg_database "
+ "WHERE datname='template0'");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ dbres = executeQueryOrDie(conn,
+ "SELECT encoding, datlocprovider, "
+ " datcollate, datctype, daticulocale AS datlocale"
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
else
dbres = executeQueryOrDie(conn,
"SELECT encoding, 'c' AS datlocprovider, "
- " datcollate, datctype, NULL AS daticulocale "
+ " datcollate, datctype, NULL AS datlocale "
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
@@ -353,16 +359,16 @@ get_template0_info(ClusterInfo *cluster)
i_datlocprovider = PQfnumber(dbres, "datlocprovider");
i_datcollate = PQfnumber(dbres, "datcollate");
i_datctype = PQfnumber(dbres, "datctype");
- i_daticulocale = PQfnumber(dbres, "daticulocale");
+ i_datlocale = PQfnumber(dbres, "datlocale");
locale->db_encoding = atoi(PQgetvalue(dbres, 0, i_datencoding));
locale->db_collprovider = PQgetvalue(dbres, 0, i_datlocprovider)[0];
locale->db_collate = pg_strdup(PQgetvalue(dbres, 0, i_datcollate));
locale->db_ctype = pg_strdup(PQgetvalue(dbres, 0, i_datctype));
- if (PQgetisnull(dbres, 0, i_daticulocale))
- locale->db_iculocale = NULL;
+ if (PQgetisnull(dbres, 0, i_datlocale))
+ locale->db_locale = NULL;
else
- locale->db_iculocale = pg_strdup(PQgetvalue(dbres, 0, i_daticulocale));
+ locale->db_locale = pg_strdup(PQgetvalue(dbres, 0, i_datlocale));
cluster->template0 = locale;
@@ -392,12 +398,15 @@ get_db_infos(ClusterInfo *cluster)
snprintf(query, sizeof(query),
"SELECT d.oid, d.datname, d.encoding, d.datcollate, d.datctype, ");
- if (GET_MAJOR_VERSION(cluster->major_version) < 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
+ snprintf(query + strlen(query), sizeof(query) - strlen(query),
+ "datlocprovider, datlocale, ");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "'c' AS datlocprovider, NULL AS daticulocale, ");
+ "datlocprovider, daticulocale AS datlocale, ");
else
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "datlocprovider, daticulocale, ");
+ "'c' AS datlocprovider, NULL AS datlocale, ");
snprintf(query + strlen(query), sizeof(query) - strlen(query),
"pg_catalog.pg_tablespace_location(t.oid) AS spclocation "
"FROM pg_catalog.pg_database d "
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 10c94a6c1f..bb261353bd 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -391,7 +391,7 @@ setup(char *argv0, bool *live_check)
* Copy locale and encoding information into the new cluster's template0.
*
* We need to copy the encoding, datlocprovider, datcollate, datctype, and
- * daticulocale. We don't need datcollversion because that's never set for
+ * datlocale. We don't need datcollversion because that's never set for
* template0.
*/
static void
@@ -400,7 +400,7 @@ set_locale_and_encoding(void)
PGconn *conn_new_template1;
char *datcollate_literal;
char *datctype_literal;
- char *daticulocale_literal = NULL;
+ char *datlocale_literal = NULL;
DbLocaleInfo *locale = old_cluster.template0;
prep_status("Setting locale and encoding for new cluster");
@@ -414,15 +414,29 @@ set_locale_and_encoding(void)
datctype_literal = PQescapeLiteral(conn_new_template1,
locale->db_ctype,
strlen(locale->db_ctype));
- if (locale->db_iculocale)
- daticulocale_literal = PQescapeLiteral(conn_new_template1,
- locale->db_iculocale,
- strlen(locale->db_iculocale));
+ if (locale->db_locale)
+ datlocale_literal = PQescapeLiteral(conn_new_template1,
+ locale->db_locale,
+ strlen(locale->db_locale));
else
- daticulocale_literal = pg_strdup("NULL");
+ datlocale_literal = pg_strdup("NULL");
/* update template0 in new cluster */
- if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
+ if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1700)
+ PQclear(executeQueryOrDie(conn_new_template1,
+ "UPDATE pg_catalog.pg_database "
+ " SET encoding = %d, "
+ " datlocprovider = '%c', "
+ " datcollate = %s, "
+ " datctype = %s, "
+ " datlocale = %s "
+ " WHERE datname = 'template0' ",
+ locale->db_encoding,
+ locale->db_collprovider,
+ datcollate_literal,
+ datctype_literal,
+ datlocale_literal));
+ else if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
" SET encoding = %d, "
@@ -435,7 +449,7 @@ set_locale_and_encoding(void)
locale->db_collprovider,
datcollate_literal,
datctype_literal,
- daticulocale_literal));
+ datlocale_literal));
else
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
@@ -449,7 +463,7 @@ set_locale_and_encoding(void)
PQfreemem(datcollate_literal);
PQfreemem(datctype_literal);
- PQfreemem(daticulocale_literal);
+ PQfreemem(datlocale_literal);
PQfinish(conn_new_template1);
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index d9a848cbfd..70ac424bc9 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -208,7 +208,7 @@ typedef struct
char *db_collate;
char *db_ctype;
char db_collprovider;
- char *db_iculocale;
+ char *db_locale;
int db_encoding;
} DbLocaleInfo;
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index d951ed3af0..41d06d272b 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -104,6 +104,8 @@ if ($oldnode->pg_version >= 11)
push @custom_opts, '--allow-group-access';
}
+my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
+
# Set up the locale settings for the original cluster, so that we
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
@@ -111,15 +113,22 @@ if ($oldnode->pg_version >= 11)
my $original_encoding = "6"; # UTF-8
my $original_provider = "c";
my $original_locale = "C";
-my $original_iculocale = "";
+my $original_datlocale = "";
my $provider_field = "'c' AS datlocprovider";
-my $iculocale_field = "NULL AS daticulocale";
-if ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
+my $datlocale_field = "NULL AS datlocale";
+if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$provider_field = "datlocprovider";
- $iculocale_field = "daticulocale";
+ if ($oldversion >= 17)
+ {
+ $datlocale_field = "datlocale";
+ }
+ else
+ {
+ $datlocale_field = "daticulocale AS datlocale";
+ }
$original_provider = "i";
- $original_iculocale = "fr-CA";
+ $original_datlocale = "fr-CA";
}
my @initdb_params = @custom_opts;
@@ -139,10 +148,10 @@ $oldnode->start;
my $result;
$result = $oldnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -422,10 +431,10 @@ if (-d $log_path)
# Test that upgraded cluster has original locale settings.
$result = $newnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index b6a4eb1d56..b943569050 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -937,14 +937,18 @@ listAllDbs(const char *pattern, bool verbose)
" d.datctype as \"%s\",\n",
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " d.datlocale as \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" d.daticulocale as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" NULL as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
" d.daticurules as \"%s\",\n",
@@ -4983,14 +4987,18 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " c.colllocale AS \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" c.colliculocale AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" c.collcollate AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 10c363d2ee..7396ff10c4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -29,6 +29,6 @@
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
- colliculocale => 'und' },
+ colllocale => 'und' },
]
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 5f08eb0a4a..a3e196fb53 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -42,7 +42,7 @@ CATALOG(pg_collation,3456,CollationRelationId)
#ifdef CATALOG_VARLEN /* variable-length fields start here */
text collcollate BKI_DEFAULT(_null_); /* LC_COLLATE setting */
text collctype BKI_DEFAULT(_null_); /* LC_CTYPE setting */
- text colliculocale BKI_DEFAULT(_null_); /* ICU locale ID */
+ text colllocale BKI_DEFAULT(_null_); /* locale ID */
text collicurules BKI_DEFAULT(_null_); /* ICU collation rules */
text collversion BKI_DEFAULT(_null_); /* provider-dependent
* version of collation
@@ -94,7 +94,7 @@ extern Oid CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
diff --git a/src/include/catalog/pg_database.dat b/src/include/catalog/pg_database.dat
index 4306e8a3e8..c2ba636f8d 100644
--- a/src/include/catalog/pg_database.dat
+++ b/src/include/catalog/pg_database.dat
@@ -18,7 +18,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE',
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE',
daticurules => 'ICU_RULES', datacl => '_null_' },
]
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 014baa7bab..dbd4379ffa 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -75,7 +75,7 @@ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID
text datctype BKI_FORCE_NOT_NULL;
/* ICU locale ID */
- text daticulocale;
+ text datlocale;
/* ICU collation rules */
text daticurules;
diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out
index 7a05c75967..8ca93f4dea 100644
--- a/src/test/regress/expected/collate.icu.utf8.out
+++ b/src/test/regress/expected/collate.icu.utf8.out
@@ -1024,7 +1024,7 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
@@ -1032,7 +1032,7 @@ ERROR: collation "test0" already exists
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
RESET icu_validation_level;
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index ad02772562..69060fe3c0 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -6221,9 +6221,9 @@ List of schemas
(0 rows)
\dO "no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.access.privilege"
@@ -6410,9 +6410,9 @@ cross-database references are not implemented: "no.such.schema"."no.such.languag
(0 rows)
\dO "no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.schema"."no.such.access.privilege"
@@ -6553,9 +6553,9 @@ List of text search templates
(0 rows)
\dO regression."no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp regression."no.such.schema"."no.such.access.privilege"
diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql
index 3db9e25913..03837de846 100644
--- a/src/test/regress/sql/collate.icu.utf8.sql
+++ b/src/test/regress/sql/collate.icu.utf8.sql
@@ -363,14 +363,14 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
--
2.34.1
[text/x-patch] v20-0004-Introduce-collation-provider-builtin.patch (87.0K, ../../[email protected]/5-v20-0004-Introduce-collation-provider-builtin.patch)
download | inline diff:
From 211a216706df4f4188b32fd40a89ed7af1f92d52 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 1 May 2023 15:38:29 -0700
Subject: [PATCH v20 4/6] Introduce collation provider "builtin".
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Three locales are offered by the builtin provider: C, C.UTF-8, and
PG_UNICODE_FAST.
The builtin "C" locale is equal in semantics and implementation to
the libc "C" locale (neither of which actually use libc).
The builtin "C.UTF-8" locale offers similar semantics to the libc
"C.UTF-8" locale, which is collation according to code point combined
with simple Unicode character semantics. Unlike the libc "C.UTF-8"
locale, the builtin "C.UTF-8" is available on all platforms with
consistent behavior, and benefits from additional optimizations.
The builtin "PG_UNICODE_FAST" locale offers collation according to
code point order and more complete Unicode character semantics. As the
SQL standard requires, it offers full case mappings that may increase
the length of a string, such as "ß" changing to "SS" when uppercased.
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 88 ++++--
doc/src/sgml/ref/create_collation.sgml | 11 +-
doc/src/sgml/ref/create_database.sgml | 8 +-
doc/src/sgml/ref/createdb.sgml | 2 +-
doc/src/sgml/ref/initdb.sgml | 17 +-
src/backend/catalog/pg_collation.c | 5 +-
src/backend/commands/collationcmds.c | 93 ++++--
src/backend/commands/dbcommands.c | 121 ++++++--
src/backend/regex/regc_pg_locale.c | 41 ++-
src/backend/utils/adt/formatting.c | 149 ++++++++++
src/backend/utils/adt/pg_locale.c | 167 +++++++++--
src/backend/utils/init/postinit.c | 51 +++-
src/bin/initdb/initdb.c | 58 ++--
src/bin/initdb/t/001_initdb.pl | 57 +++-
src/bin/pg_dump/pg_dump.c | 49 ++--
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 70 +++--
src/bin/psql/describe.c | 4 +-
src/bin/scripts/createdb.c | 18 +-
src/bin/scripts/t/020_createdb.pl | 78 +++++
src/include/catalog/pg_collation.dat | 6 +-
src/include/catalog/pg_collation.h | 3 +
src/include/utils/pg_locale.h | 10 +-
src/test/icu/t/010_database.pl | 22 +-
src/test/regress/expected/collate.out | 24 +-
src/test/regress/expected/collate.utf8.out | 288 +++++++++++++++++++
src/test/regress/expected/collate.utf8_1.out | 8 +
src/test/regress/parallel_schedule | 4 +-
src/test/regress/sql/collate.sql | 10 +
src/test/regress/sql/collate.utf8.sql | 123 ++++++++
29 files changed, 1422 insertions(+), 163 deletions(-)
create mode 100644 src/test/regress/expected/collate.utf8.out
create mode 100644 src/test/regress/expected/collate.utf8_1.out
create mode 100644 src/test/regress/sql/collate.utf8.sql
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 4fc143025e..7fe4a9bc39 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -342,22 +342,14 @@ initdb --locale=sv_SE
<title>Locale Providers</title>
<para>
- <productname>PostgreSQL</productname> supports multiple <firstterm>locale
- providers</firstterm>. This specifies which library supplies the locale
- data. One standard provider name is <literal>libc</literal>, which uses
- the locales provided by the operating system C library. These are the
- locales used by most tools provided by the operating system. Another
- provider is <literal>icu</literal>, which uses the external
- ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can
- only be used if support for ICU was configured when PostgreSQL was built.
+ A locale provider specifies which library defines the locale behavior for
+ collations and character classifications.
</para>
<para>
The commands and tools that select the locale settings, as described
- above, each have an option to select the locale provider. The examples
- shown earlier all use the <literal>libc</literal> provider, which is the
- default. Here is an example to initialize a database cluster using the
- ICU provider:
+ above, each have an option to select the locale provider. Here is an
+ example to initialize a database cluster using the ICU provider:
<programlisting>
initdb --locale-provider=icu --icu-locale=en
</programlisting>
@@ -370,12 +362,74 @@ initdb --locale-provider=icu --icu-locale=en
</para>
<para>
- Which locale provider to use depends on individual requirements. For most
- basic uses, either provider will give adequate results. For the libc
- provider, it depends on what the operating system offers; some operating
- systems are better than others. For advanced uses, ICU offers more locale
- variants and customization options.
+ Regardless of the locale provider, the operating system is still used to
+ provide some locale-aware behavior, such as messages (see <xref
+ linkend="guc-lc-messages"/>).
</para>
+
+ <para>
+ The available locale providers are listed below.
+ </para>
+
+ <sect3 id="locale-provider-builtin">
+ <title>Builtin</title>
+ <para>
+ The <literal>builtin</literal> provider uses built-in operations. Only
+ the <literal>C</literal> and <literal>C.UTF-8</literal> locales are
+ supported for this provider.
+ </para>
+ <para>
+ The <literal>C</literal> locale behavior is identical to the
+ <literal>C</literal> locale in the libc provider. When using this locale,
+ the behavior may depend on the database encoding.
+ </para>
+ <para>
+ The <literal>C.UTF-8</literal> locale is available only for when the
+ database encoding is <literal>UTF-8</literal>, and the behavior is based
+ on Unicode. The collation uses the code point values only. The regular
+ expression character classes are based on the "POSIX Compatible"
+ semantics, and the case mapping is the "simple" variant.
+ </para>
+ </sect3>
+ <sect3 id="locale-provider-icu">
+ <title>ICU</title>
+ <para>
+ The <literal>icu</literal> provider uses the external
+ ICU<indexterm><primary>ICU</primary></indexterm>
+ library. <productname>PostgreSQL</productname> must have been configured
+ with support.
+ </para>
+ <para>
+ ICU provides collation and character classification behavior that is
+ independent of the operating system and database encoding, which is
+ preferable if you expect to transition to other platforms without any
+ change in results. <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal> can be set independently of the ICU locale.
+ </para>
+ <note>
+ <para>
+ For the ICU provider, results may depend on the version of the ICU
+ library used, as it is updated to reflect changes in natural language
+ over time.
+ </para>
+ </note>
+ </sect3>
+ <sect3 id="locale-provider-libc">
+ <title>libc</title>
+ <para>
+ The <literal>libc</literal> provider uses the operating system's C
+ library. The collation and character classification behavior is
+ controlled by the settings <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal>, so they cannot be set independently.
+ </para>
+ <note>
+ <para>
+ The same locale name may have different behavior on different platforms
+ when using the libc provider.
+ </para>
+ </note>
+ </sect3>
+
</sect2>
<sect2 id="icu-locales">
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 5cf9777764..85f18cbbe5 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -96,6 +96,11 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<replaceable>locale</replaceable>, you cannot specify either of those
parameters.
</para>
+ <para>
+ If <replaceable>provider</replaceable> is <literal>builtin</literal>,
+ then <replaceable>locale</replaceable> must be specified and set to
+ either <literal>C</literal> or <literal>C.UTF-8</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -129,9 +134,9 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<listitem>
<para>
Specifies the provider to use for locale services associated with this
- collation. Possible values are
- <literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
- (if the server was built with ICU support) or <literal>libc</literal>.
+ collation. Possible values are <literal>builtin</literal>,
+ <literal>icu</literal><indexterm><primary>ICU</primary></indexterm> (if
+ the server was built with ICU support) or <literal>libc</literal>.
<literal>libc</literal> is the default. See <xref
linkend="locale-providers"/> for details.
</para>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 72927960eb..1f5cdf1271 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -162,6 +162,12 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
linkend="create-database-lc-ctype"/>, or <xref
linkend="create-database-icu-locale"/> individually.
</para>
+ <para>
+ If <xref linkend="create-database-locale-provider"/> is
+ <literal>builtin</literal>, then <replaceable>locale</replaceable>
+ must be specified and set to either <literal>C</literal> or
+ <literal>C.UTF-8</literal>.
+ </para>
<tip>
<para>
The other locale settings <xref linkend="guc-lc-messages"/>, <xref
@@ -243,7 +249,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<listitem>
<para>
Specifies the provider to use for the default collation in this
- database. Possible values are
+ database. Possible values are <literal>builtin</literal>,
<literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
(if the server was built with ICU support) or <literal>libc</literal>.
By default, the provider is the same as that of the <xref
diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml
index e4647d5ce7..d3e815f659 100644
--- a/doc/src/sgml/ref/createdb.sgml
+++ b/doc/src/sgml/ref/createdb.sgml
@@ -171,7 +171,7 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
Specifies the locale provider for the database's default collation.
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index cd75cae10e..08a1c2538f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -286,6 +286,11 @@ PostgreSQL documentation
environment that <command>initdb</command> runs in. Locale
support is described in <xref linkend="locale"/>.
</para>
+ <para>
+ If <option>--locale-provider</option> is <literal>builtin</literal>,
+ <option>--locale</option> must be specified and set to
+ <literal>C</literal> or <literal>C.UTF-8</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -314,8 +319,18 @@ PostgreSQL documentation
</listitem>
</varlistentry>
+ <varlistentry id="app-initdb-builtin-locale">
+ <term><option>--builtin-locale=<replaceable>locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the locale name when the builtin provider is used. Locale support
+ is described in <xref linkend="locale"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-initdb-option-locale-provider">
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
This option sets the locale provider for databases created in the new
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 7bad94f908..01e91000af 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -68,7 +68,10 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colllocale);
+ Assert((collprovider == COLLPROVIDER_LIBC &&
+ collcollate && collctype && !colllocale) ||
+ (collprovider != COLLPROVIDER_LIBC &&
+ !collcollate && !collctype && colllocale));
/*
* Make sure there is no existing collation of same name & encoding.
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 27564e569a..0fa073496e 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -68,7 +68,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colllocale;
+ const char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -215,7 +215,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (collproviderstr)
{
- if (pg_strcasecmp(collproviderstr, "icu") == 0)
+ if (pg_strcasecmp(collproviderstr, "builtin") == 0)
+ collprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(collproviderstr, "icu") == 0)
collprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(collproviderstr, "libc") == 0)
collprovider = COLLPROVIDER_LIBC;
@@ -245,7 +247,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (lcctypeEl)
collctype = defGetString(lcctypeEl);
- if (collprovider == COLLPROVIDER_LIBC)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ if (!colllocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("parameter \"locale\" must be specified")));
+
+ colllocale = builtin_validate_locale(GetDatabaseEncoding(),
+ colllocale);
+ }
+ else if (collprovider == COLLPROVIDER_LIBC)
{
if (!collcollate)
ereport(ERROR,
@@ -305,7 +317,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
- if (collprovider == COLLPROVIDER_ICU)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * Behavior may be different in different encodings, so set
+ * collencoding to the current database encoding. No validation is
+ * required, because the "builtin" provider is compatible with any
+ * encoding.
+ */
+ collencoding = GetDatabaseEncoding();
+ }
+ else if (collprovider == COLLPROVIDER_ICU)
{
#ifdef USE_ICU
/*
@@ -334,7 +356,18 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
+ {
+ const char *locale;
+
+ if (collprovider == COLLPROVIDER_ICU)
+ locale = colllocale;
+ else if (collprovider == COLLPROVIDER_LIBC)
+ locale = collcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ collversion = get_collation_actual_version(collprovider, locale);
+ }
newoid = CollationCreate(collName,
collNamespace,
@@ -409,6 +442,7 @@ AlterCollation(AlterCollationStmt *stmt)
Form_pg_collation collForm;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
ObjectAddress address;
@@ -435,8 +469,20 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
+ if (collForm->collprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (collForm->collprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(collForm->collprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -500,11 +546,18 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_datlocale : Anum_pg_database_datcollate);
-
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(dbtup);
}
@@ -521,11 +574,19 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttrNotNull(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(colltp);
}
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index d1de46e759..d7a21adc5c 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -698,6 +698,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
DefElem *dtemplate = NULL;
DefElem *dencoding = NULL;
DefElem *dlocale = NULL;
+ DefElem *dbuiltinlocale = NULL;
DefElem *dcollate = NULL;
DefElem *dctype = NULL;
DefElem *diculocale = NULL;
@@ -713,7 +714,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dblocale = NULL;
+ const char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -762,6 +763,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errorConflictingDefElem(defel, pstate);
dlocale = defel;
}
+ else if (strcmp(defel->defname, "builtin_locale") == 0)
+ {
+ if (dbuiltinlocale)
+ errorConflictingDefElem(defel, pstate);
+ dbuiltinlocale = defel;
+ }
else if (strcmp(defel->defname, "lc_collate") == 0)
{
if (dcollate)
@@ -897,7 +904,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
dbcollate = defGetString(dlocale);
dbctype = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
}
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ dblocale = defGetString(dbuiltinlocale);
if (dcollate && dcollate->arg)
dbcollate = defGetString(dcollate);
if (dctype && dctype->arg)
@@ -910,7 +920,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *locproviderstr = defGetString(dlocprovider);
- if (pg_strcasecmp(locproviderstr, "icu") == 0)
+ if (pg_strcasecmp(locproviderstr, "builtin") == 0)
+ dblocprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(locproviderstr, "icu") == 0)
dblocprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(locproviderstr, "libc") == 0)
dblocprovider = COLLPROVIDER_LIBC;
@@ -1027,14 +1039,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
- {
- if (dlocale && dlocale->arg)
- dblocale = defGetString(dlocale);
- else
- dblocale = src_locale;
- }
- if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL)
+ dblocale = src_locale;
+ if (dbicurules == NULL)
dbicurules = src_icurules;
/* Some encodings are client only */
@@ -1059,6 +1066,27 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
check_encoding_locale_matches(encoding, dbcollate, dbctype);
+ if (dblocprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * This would happen if template0 uses the libc provider but the new
+ * database uses builtin.
+ */
+ if (!dblocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("LOCALE must be specified for the builtin provider")));
+
+ dblocale = builtin_validate_locale(encoding, dblocale);
+ }
+ else
+ {
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("BUILTIN_LOCALE cannot be specified unless locale provider is builtin")));
+ }
+
if (dblocprovider == COLLPROVIDER_ICU)
{
if (!(is_encoding_supported_by_icu(encoding)))
@@ -1100,7 +1128,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
}
else
{
- if (dblocale)
+ if (diculocale && diculocale->arg)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1111,6 +1139,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
}
+ /* for libc, locale comes from datcollate and datctype */
+ if (dblocprovider == COLLPROVIDER_LIBC)
+ dblocale = NULL;
+
/*
* Check that the new encoding and locale settings match the source
* database. We insist on this because we simply copy the source data ---
@@ -1196,8 +1228,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (src_collversion && !dcollversion)
{
char *actual_versionstr;
+ const char *locale;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ actual_versionstr = get_collation_actual_version(dblocprovider, locale);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1225,7 +1265,18 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ {
+ const char *locale;
+
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ dbcollversion = get_collation_actual_version(dblocprovider, locale);
+ }
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1364,8 +1415,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dblocale));
+ Assert((dblocprovider != COLLPROVIDER_LIBC && dblocale) ||
+ (dblocprovider == COLLPROVIDER_LIBC && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -2446,6 +2497,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
ObjectAddress address;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
@@ -2472,10 +2524,24 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
- newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
+ if (datForm->datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datlocale, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datForm->datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(datForm->datlocprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -2660,6 +2726,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
+ char *locale;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2670,8 +2737,20 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
- version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
+ if (datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ version = get_collation_actual_version(datlocprovider, locale);
ReleaseSysCache(tp);
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 6a26388bfa..d612731319 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -16,6 +16,8 @@
*/
#include "catalog/pg_collation.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "utils/pg_locale.h"
/*
@@ -64,6 +66,7 @@
typedef enum
{
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
+ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
@@ -75,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -266,7 +271,15 @@ pg_set_regex_collation(Oid collation)
if (GetDatabaseEncoding() == PG_UTF8)
{
if (pg_regex_locale)
- pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ {
+ if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
+ pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = pg_regex_locale->info.builtin.properties_posix;
+ }
+ else
+ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
@@ -290,6 +303,8 @@ pg_wc_isdigit(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -322,6 +337,8 @@ pg_wc_isalpha(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALPHA));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
@@ -354,6 +371,8 @@ pg_wc_isalnum(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -395,6 +414,8 @@ pg_wc_isupper(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISUPPER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
@@ -427,6 +448,8 @@ pg_wc_islower(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISLOWER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
@@ -459,6 +482,8 @@ pg_wc_isgraph(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISGRAPH));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
@@ -491,6 +516,8 @@ pg_wc_isprint(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPRINT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
@@ -523,6 +550,8 @@ pg_wc_ispunct(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
@@ -555,6 +584,8 @@ pg_wc_isspace(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISSPACE));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
@@ -588,6 +619,8 @@ pg_wc_toupper(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_uppercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -628,6 +661,8 @@ pg_wc_tolower(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_lowercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -792,6 +827,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
#endif
break;
+ case PG_REGEX_BUILTIN:
+ max_chr = (pg_wchar) MAX_SIMPLE_CHR;
+ break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
@@ -809,6 +847,7 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break;
default:
+ Assert(false);
max_chr = 0; /* can't get here, but keep compiler quiet */
break;
}
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 829aaa8d0e..0d3ce8a33e 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -77,6 +77,8 @@
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "mb/pg_wchar.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
@@ -1680,6 +1682,35 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
@@ -1798,6 +1829,35 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
@@ -1861,6 +1921,48 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
return result;
}
+struct WordBoundaryState
+{
+ const char *str;
+ size_t len;
+ size_t offset;
+ bool init;
+ bool prev_alnum;
+ bool posix;
+};
+
+/*
+ * Simple word boundary iterator that draws boundaries each time the result of
+ * pg_u_isalnum() changes.
+ */
+static size_t
+initcap_wbnext(void *state)
+{
+ struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
+
+ while (wbstate->offset < wbstate->len &&
+ wbstate->str[wbstate->offset] != '\0')
+ {
+ pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ wbstate->offset);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
+
+ if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
+ {
+ size_t prev_offset = wbstate->offset;
+
+ wbstate->init = true;
+ wbstate->offset += unicode_utf8len(u);
+ wbstate->prev_alnum = curr_alnum;
+ return prev_offset;
+ }
+
+ wbstate->offset += unicode_utf8len(u);
+ }
+
+ return wbstate->len;
+}
+
/*
* collation-aware, wide-character-aware initcap function
*
@@ -1917,6 +2019,53 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+ struct WordBoundaryState wbstate = {
+ .str = src,
+ .len = srclen,
+ .offset = 0,
+ .init = false,
+ .prev_alnum = false,
+ .posix = mylocale->info.builtin.properties_posix,
+ };
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.titlecase,
+ mylocale->info.builtin.adjust_to_cased,
+ mylocale->info.builtin.casemap_full,
+ initcap_wbnext, &wbstate);
+ if (needed + 1 > dstsize)
+ {
+ /* reset iterator */
+ wbstate.offset = 0;
+ wbstate.prev_alnum = false;
+
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.titlecase,
+ mylocale->info.builtin.adjust_to_cased,
+ mylocale->info.builtin.casemap_full,
+ initcap_wbnext, &wbstate);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
if (pg_database_encoding_max_length() > 1)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 45fe847320..0c129cd3ca 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1269,7 +1269,19 @@ lookup_collation_cache(Oid collation, bool set_flags)
elog(ERROR, "cache lookup failed for collation %u", collation);
collform = (Form_pg_collation) GETSTRUCT(tp);
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ Datum datum;
+ const char *colllocale;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ colllocale = TextDatumGetCString(datum);
+
+ cache_entry->collate_is_c = true;
+ cache_entry->ctype_is_c = ((strcmp(colllocale, "C") == 0) ||
+ (strcmp(colllocale, "POSIX") == 0));
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
const char *collcollate;
@@ -1320,16 +1332,30 @@ lc_collate_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_COLLATE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_COLLATE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ result = true;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1373,16 +1399,29 @@ lc_ctype_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_CTYPE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_CTYPE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ localeptr = default_locale.info.builtin.locale;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1390,6 +1429,7 @@ lc_ctype_is_c(Oid collation)
result = true;
else
result = false;
+
return (bool) result;
}
@@ -1520,10 +1560,10 @@ pg_newlocale_from_collation(Oid collid)
if (collid == DEFAULT_COLLATION_OID)
{
- if (default_locale.provider == COLLPROVIDER_ICU)
- return &default_locale;
- else
+ if (default_locale.provider == COLLPROVIDER_LIBC)
return (pg_locale_t) 0;
+ else
+ return &default_locale;
}
cache_entry = lookup_collation_cache(collid, false);
@@ -1548,7 +1588,50 @@ pg_newlocale_from_collation(Oid collid)
result.provider = collform->collprovider;
result.deterministic = collform->collisdeterministic;
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ bool casemap_full;
+ bool adjust_to_cased;
+ bool titlecase;
+ bool properties_posix;
+
+ const char *locstr;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ locstr = TextDatumGetCString(datum);
+
+ if (strcmp(locstr, "PG_UNICODE_FAST") == 0)
+ {
+ casemap_full = true;
+ adjust_to_cased = true;
+ titlecase = true;
+ properties_posix = false;
+ }
+ else if (strcmp(locstr, "C.UTF-8") == 0)
+ {
+ casemap_full = false;
+ adjust_to_cased = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else if (strcmp(locstr, "C") == 0)
+ {
+ casemap_full = false;
+ adjust_to_cased = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else
+ elog(ERROR, "unexpected builtin locale: %s", locstr);
+
+ result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
+ locstr);
+ result.info.builtin.casemap_full = casemap_full;
+ result.info.builtin.adjust_to_cased = adjust_to_cased;
+ result.info.builtin.titlecase = titlecase;
+ result.info.builtin.properties_posix = properties_posix;
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
const char *collcollate;
const char *collctype pg_attribute_unused();
@@ -1627,6 +1710,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
+ Assert(collform->collprovider != COLLPROVIDER_BUILTIN);
datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
@@ -1678,6 +1762,14 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
+ /*
+ * The only two supported locales (C and C.UTF-8) are both based on memcmp
+ * and do not change. (The ctype behavior can change, but the versioning
+ * does not track that.)
+ */
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ return NULL;
+
#ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU)
{
@@ -2444,6 +2536,43 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
return result;
}
+const char *
+builtin_validate_locale(int encoding, const char *locale)
+{
+ const char *canonical_name = NULL;
+ int required_encoding = -1;
+
+ if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0)
+ {
+ canonical_name = "C";
+ }
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "PG_UNICODE_FAST";
+ }
+ else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "C.UTF-8";
+ }
+
+ if (!canonical_name)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ locale)));
+
+ if (required_encoding >= 0 && encoding != required_encoding)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("encoding \"%s\" does not match locale \"%s\"",
+ pg_encoding_to_char(encoding), locale)));
+
+ return canonical_name;
+}
+
+
#ifdef USE_ICU
/*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 154912ecb4..95c00f559d 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -425,7 +425,48 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
strcmp(ctype, "POSIX") == 0)
database_ctype_is_c = true;
- if (dbform->datlocprovider == COLLPROVIDER_ICU)
+ if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
+ {
+ bool casemap_full;
+ bool adjust_to_cased;
+ bool titlecase;
+ bool properties_posix;
+
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
+
+ if (strcmp(datlocale, "PG_UNICODE_FAST") == 0)
+ {
+ casemap_full = true;
+ adjust_to_cased = true;
+ titlecase = true;
+ properties_posix = false;
+ }
+ else if (strcmp(datlocale, "C.UTF-8") == 0)
+ {
+ casemap_full = false;
+ adjust_to_cased = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else if (strcmp(datlocale, "C") == 0)
+ {
+ casemap_full = false;
+ adjust_to_cased = false;
+ titlecase = false;
+ properties_posix = true;
+ }
+ else
+ elog(ERROR, "unexpected builtin locale: %s", datlocale);
+
+ default_locale.info.builtin.locale = MemoryContextStrdup(
+ TopMemoryContext, datlocale);
+ default_locale.info.builtin.casemap_full = casemap_full;
+ default_locale.info.builtin.adjust_to_cased = adjust_to_cased;
+ default_locale.info.builtin.titlecase = titlecase;
+ default_locale.info.builtin.properties_posix = properties_posix;
+ }
+ else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
char *icurules;
@@ -463,10 +504,16 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *actual_versionstr;
char *collversionstr;
+ char *locale;
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
+ if (dbform->datlocprovider == COLLPROVIDER_LIBC)
+ locale = collate;
+ else
+ locale = datlocale;
+
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 90f793632a..7419c38722 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -146,6 +146,7 @@ static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
static char *datlocale = NULL;
+static bool icu_locale_specified = false;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -2390,14 +2391,13 @@ setlocales(void)
lc_messages = canonname;
#endif
+ if (locale_provider != COLLPROVIDER_LIBC && datlocale == NULL)
+ pg_fatal("locale must be specified unless provider is libc");
+
if (locale_provider == COLLPROVIDER_ICU)
{
char *langtag;
- /* acquire default locale from the environment, if not specified */
- if (datlocale == NULL)
- pg_fatal("ICU locale must be specified");
-
/* canonicalize to a language tag */
langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
@@ -2442,7 +2442,8 @@ usage(const char *progname)
" set default locale in the respective category for\n"
" new databases (default taken from environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --builtin-locale=LOCALE set builtin locale name for new databases\n"));
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" set default locale provider for new databases\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
printf(_(" -T, --text-search-config=CFG\n"
@@ -2593,20 +2594,28 @@ setup_locale_encoding(void)
{
setlocales();
- if (locale_provider == COLLPROVIDER_LIBC &&
- strcmp(lc_ctype, lc_collate) == 0 &&
- strcmp(lc_ctype, lc_time) == 0 &&
- strcmp(lc_ctype, lc_numeric) == 0 &&
- strcmp(lc_ctype, lc_monetary) == 0 &&
- strcmp(lc_ctype, lc_messages) == 0 &&
- (!datlocale || strcmp(lc_ctype, datlocale) == 0))
+ if (locale_provider == COLLPROVIDER_BUILTIN &&
+ strcmp(lc_ctype, "C") == 0 &&
+ strcmp(lc_collate, "C") == 0 &&
+ strcmp(lc_time, "C") == 0 &&
+ strcmp(lc_numeric, "C") == 0 &&
+ strcmp(lc_monetary, "C") == 0 &&
+ strcmp(lc_messages, "C") == 0)
+ printf(_("The database cluster will be initialized with no locale.\n"));
+ else if (locale_provider == COLLPROVIDER_LIBC &&
+ strcmp(lc_ctype, lc_collate) == 0 &&
+ strcmp(lc_ctype, lc_time) == 0 &&
+ strcmp(lc_ctype, lc_numeric) == 0 &&
+ strcmp(lc_ctype, lc_monetary) == 0 &&
+ strcmp(lc_ctype, lc_messages) == 0 &&
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
- printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (datlocale)
- printf(_(" ICU locale: %s\n"), datlocale);
+ printf(_(" default collation provider: %s\n"), collprovider_name(locale_provider));
+ if (locale_provider != COLLPROVIDER_LIBC)
+ printf(_(" default collation locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3099,9 +3108,10 @@ main(int argc, char *argv[])
{"allow-group-access", no_argument, NULL, 'g'},
{"discard-caches", no_argument, NULL, 14},
{"locale-provider", required_argument, NULL, 15},
- {"icu-locale", required_argument, NULL, 16},
- {"icu-rules", required_argument, NULL, 17},
- {"sync-method", required_argument, NULL, 18},
+ {"builtin-locale", required_argument, NULL, 16},
+ {"icu-locale", required_argument, NULL, 17},
+ {"icu-rules", required_argument, NULL, 18},
+ {"sync-method", required_argument, NULL, 19},
{NULL, 0, NULL, 0}
};
@@ -3269,7 +3279,9 @@ main(int argc, char *argv[])
"-c debug_discard_caches=1");
break;
case 15:
- if (strcmp(optarg, "icu") == 0)
+ if (strcmp(optarg, "builtin") == 0)
+ locale_provider = COLLPROVIDER_BUILTIN;
+ else if (strcmp(optarg, "icu") == 0)
locale_provider = COLLPROVIDER_ICU;
else if (strcmp(optarg, "libc") == 0)
locale_provider = COLLPROVIDER_LIBC;
@@ -3280,9 +3292,13 @@ main(int argc, char *argv[])
datlocale = pg_strdup(optarg);
break;
case 17:
- icu_rules = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
+ icu_locale_specified = true;
break;
case 18:
+ icu_rules = pg_strdup(optarg);
+ break;
+ case 19:
if (!parse_sync_method(optarg, &sync_method))
exit(1);
break;
@@ -3312,7 +3328,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (datlocale && locale_provider != COLLPROVIDER_ICU)
+ if (icu_locale_specified && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 03376cc0f7..242f4581a5 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -117,7 +117,7 @@ if ($ENV{with_icu} eq 'yes')
{
command_fails_like(
[ 'initdb', '--no-sync', '--locale-provider=icu', "$tempdir/data2" ],
- qr/initdb: error: ICU locale must be specified/,
+ qr/initdb: error: locale must be specified unless provider is libc/,
'locale provider ICU requires --icu-locale');
command_ok(
@@ -138,7 +138,7 @@ if ($ENV{with_icu} eq 'yes')
'--lc-monetary=C', '--lc-time=C',
"$tempdir/data4"
],
- qr/^\s+ICU locale:\s+und\n/ms,
+ qr/^\s+default collation locale:\s+und\n/ms,
'options --locale-provider=icu --locale=und --lc-*=C');
command_fails_like(
@@ -184,6 +184,59 @@ else
'locale provider ICU fails since no ICU support');
}
+command_fails(
+ [ 'initdb', '--no-sync', '--locale-provider=builtin', "$tempdir/data6" ],
+ 'locale provider builtin fails without --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--locale=C',
+ "$tempdir/data7"
+ ],
+ 'locale provider builtin with --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E SQL_ASCII',
+ '--builtin-locale=C.UTF-8', "$tempdir/data9"
+ ],
+ 'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
+);
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--lc-ctype=C',
+ '--locale=C', "$tempdir/data10"
+ ],
+ 'locale provider builtin with --lc-ctype');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-locale=en',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU locale');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-rules=""',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU rules');
+
command_fails(
[ 'initdb', '--no-sync', '--locale-provider=xyz', "$tempdir/dataX" ],
'fails for invalid locale provider');
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index a67b4b8225..450c322205 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3114,7 +3114,9 @@ dumpDatabase(Archive *fout)
}
appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
- if (datlocprovider[0] == 'c')
+ if (datlocprovider[0] == 'b')
+ appendPQExpBufferStr(creaQry, "builtin");
+ else if (datlocprovider[0] == 'c')
appendPQExpBufferStr(creaQry, "libc");
else if (datlocprovider[0] == 'i')
appendPQExpBufferStr(creaQry, "icu");
@@ -3122,27 +3124,33 @@ dumpDatabase(Archive *fout)
pg_fatal("unrecognized locale provider: %s",
datlocprovider);
- if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ if (!locale && datlocprovider[0] != 'c')
+ pg_log_warning("database '%s' with provider '%s' missing datlocale",
+ datname, datlocprovider);
+
+ if (locale && datlocprovider[0] == 'c')
+ pg_log_warning("database '%s' with provider 'c' has non-NULL locale '%s'",
+ datname, locale);
+
+ /* if collate and ctype are equal, and locale is NULL, use LOCALE */
+ if (!locale && strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ locale = collate;
+
+ /* output LC_COLLATE and LC_CTYPE if different from LOCALE */
+ if (strlen(collate) > 0 && (!locale || strcmp(collate, locale) != 0))
{
- appendPQExpBufferStr(creaQry, " LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
appendStringLiteralAH(creaQry, collate, fout);
}
- else
+ if (strlen(ctype) > 0 && (!locale || strcmp(ctype, locale) != 0))
{
- if (strlen(collate) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
- appendStringLiteralAH(creaQry, collate, fout);
- }
- if (strlen(ctype) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
- appendStringLiteralAH(creaQry, ctype, fout);
- }
+ appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+ appendStringLiteralAH(creaQry, ctype, fout);
}
+
if (locale)
{
- appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LOCALE = ");
appendStringLiteralAH(creaQry, locale, fout);
}
@@ -13870,7 +13878,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
fmtQualifiedDumpable(collinfo));
appendPQExpBufferStr(q, "provider = ");
- if (collprovider[0] == 'c')
+ if (collprovider[0] == 'b')
+ appendPQExpBufferStr(q, "builtin");
+ else if (collprovider[0] == 'c')
appendPQExpBufferStr(q, "libc");
else if (collprovider[0] == 'i')
appendPQExpBufferStr(q, "icu");
@@ -13891,6 +13901,13 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
/* no locale -- the default collation cannot be reloaded anyway */
}
+ else if (collprovider[0] == 'b')
+ {
+ if (collcollate || collctype || colllocale || collicurules)
+ pg_log_warning("invalid collation \"%s\"", qcollname);
+
+ appendPQExpBufferStr(q, ", locale = 'C'");
+ }
else if (collprovider[0] == 'i')
{
if (fout->remoteVersion >= 150000)
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index 41d06d272b..94bf086ba8 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -110,13 +110,16 @@ my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
-my $original_encoding = "6"; # UTF-8
-my $original_provider = "c";
-my $original_locale = "C";
-my $original_datlocale = "";
-my $provider_field = "'c' AS datlocprovider";
-my $datlocale_field = "NULL AS datlocale";
-if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+my %encoding_number = ('UTF-8' => 6, 'SQL_ASCII' => 0);
+my $provider_field;
+my $datlocale_field;
+my $original_encoding;
+my $original_provider;
+my $original_datcollate = "C";
+my $original_datctype = "C";
+my $original_datlocale;
+
+if ($oldversion >= 15)
{
$provider_field = "datlocprovider";
if ($oldversion >= 17)
@@ -127,18 +130,52 @@ if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$datlocale_field = "daticulocale AS datlocale";
}
+}
+else
+{
+ $provider_field = "'c' AS datlocprovider";
+ $datlocale_field = "NULL AS datlocale";
+}
+
+if ($oldversion >= 17)
+{
+ $original_encoding = "UTF-8";
+ $original_provider = "b";
+ $original_datlocale = "C.UTF-8";
+}
+elsif ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+{
+ $original_encoding = "UTF-8";
$original_provider = "i";
$original_datlocale = "fr-CA";
}
+else
+{
+ my $original_encoding = "SQL_ASCII";
+ my $original_provider = "c";
+ my $original_datlocale = "";
+}
my @initdb_params = @custom_opts;
-push @initdb_params, ('--encoding', 'UTF-8');
-push @initdb_params, ('--locale', $original_locale);
-if ($original_provider eq "i")
+push @initdb_params, ('--encoding', $original_encoding);
+push @initdb_params, ('--lc-collate', $original_datcollate);
+push @initdb_params, ('--lc-ctype', $original_datctype);
+
+# add --locale-provider, if supported
+my %provider_name = ('b' => 'builtin', 'i' => 'icu', 'c' => 'libc');
+if ($oldnode->pg_version >= 15)
{
- push @initdb_params, ('--locale-provider', 'icu');
- push @initdb_params, ('--icu-locale', 'fr-CA');
+ push @initdb_params,
+ ('--locale-provider', $provider_name{$original_provider});
+ if ($original_provider eq 'b')
+ {
+ push @initdb_params, ('--builtin-locale', $original_datlocale);
+ }
+ elsif ($original_provider eq 'i')
+ {
+ push @initdb_params, ('--icu-locale', $original_datlocale);
+ }
}
$node_params{extra} = \@initdb_params;
@@ -151,7 +188,7 @@ $result = $oldnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -327,7 +364,8 @@ if (defined($ENV{oldinstall}))
}
# Create an invalid database, will be deleted below
-$oldnode->safe_psql('postgres', qq(
+$oldnode->safe_psql(
+ 'postgres', qq(
CREATE DATABASE regression_invalid;
UPDATE pg_database SET datconnlimit = -2 WHERE datname = 'regression_invalid';
));
@@ -370,7 +408,7 @@ command_checks_all(
$mode, '--check',
],
1,
- [qr/invalid/], # pg_upgrade prints errors on stdout :(
+ [qr/invalid/], # pg_upgrade prints errors on stdout :(
[qr//],
'invalid database causes failure');
rmtree($newnode->data_dir . "/pg_upgrade_output.d");
@@ -434,7 +472,7 @@ $result = $newnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index b943569050..c649477505 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -926,7 +926,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Encoding"));
if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
- " CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE d.datlocprovider WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Locale Provider"));
else
appendPQExpBuffer(&buf,
@@ -4974,7 +4974,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
if (pset.sversion >= 100000)
appendPQExpBuffer(&buf,
- " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Provider"));
else
appendPQExpBuffer(&buf,
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
index 14970a6a5f..4af4b98181 100644
--- a/src/bin/scripts/createdb.c
+++ b/src/bin/scripts/createdb.c
@@ -40,8 +40,9 @@ main(int argc, char *argv[])
{"locale", required_argument, NULL, 'l'},
{"maintenance-db", required_argument, NULL, 3},
{"locale-provider", required_argument, NULL, 4},
- {"icu-locale", required_argument, NULL, 5},
- {"icu-rules", required_argument, NULL, 6},
+ {"builtin-locale", required_argument, NULL, 5},
+ {"icu-locale", required_argument, NULL, 6},
+ {"icu-rules", required_argument, NULL, 7},
{NULL, 0, NULL, 0}
};
@@ -67,6 +68,7 @@ main(int argc, char *argv[])
char *lc_ctype = NULL;
char *locale = NULL;
char *locale_provider = NULL;
+ char *builtin_locale = NULL;
char *icu_locale = NULL;
char *icu_rules = NULL;
@@ -134,9 +136,12 @@ main(int argc, char *argv[])
locale_provider = pg_strdup(optarg);
break;
case 5:
- icu_locale = pg_strdup(optarg);
+ builtin_locale = pg_strdup(optarg);
break;
case 6:
+ icu_locale = pg_strdup(optarg);
+ break;
+ case 7:
icu_rules = pg_strdup(optarg);
break;
default:
@@ -216,6 +221,11 @@ main(int argc, char *argv[])
appendPQExpBufferStr(&sql, " LOCALE ");
appendStringLiteralConn(&sql, locale, conn);
}
+ if (builtin_locale)
+ {
+ appendPQExpBufferStr(&sql, " BUILTIN_LOCALE ");
+ appendStringLiteralConn(&sql, builtin_locale, conn);
+ }
if (lc_collate)
{
appendPQExpBufferStr(&sql, " LC_COLLATE ");
@@ -296,7 +306,7 @@ help(const char *progname)
printf(_(" --lc-ctype=LOCALE LC_CTYPE setting for the database\n"));
printf(_(" --icu-locale=LOCALE ICU locale setting for the database\n"));
printf(_(" --icu-rules=RULES ICU rules setting for the database\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" locale provider for the database's default collation\n"));
printf(_(" -O, --owner=OWNER database user to own the new database\n"));
printf(_(" -S, --strategy=STRATEGY database creation strategy wal_log or file_copy\n"));
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index 37e47b0078..3ba623f9d1 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -105,6 +105,84 @@ else
'create database with ICU fails since no ICU support');
}
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ 'tbuiltin1'
+ ],
+ 'create database with provider "builtin" fails without --locale');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin2'
+ ],
+ 'create database with provider "builtin" and locale "C"');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-collate=C',
+ 'tbuiltin3'
+ ],
+ 'create database with provider "builtin" and LC_COLLATE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-ctype=C',
+ 'tbuiltin4'
+ ],
+ 'create database with provider "builtin" and LC_CTYPE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E UTF-8', '--builtin-locale=C.UTF8',
+ 'tbuiltin5'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E LATIN1', '--builtin-locale=C.UTF-8',
+ 'tbuiltin6'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-locale=en',
+ 'tbuiltin7'
+ ],
+ 'create database with provider "builtin" and ICU_LOCALE="en"');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-rules=""',
+ 'tbuiltin8'
+ ],
+ 'create database with provider "builtin" and ICU_RULES=""');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template1', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin9'
+ ],
+ 'create database with provider "builtin" not matching template');
+
$node->command_fails([ 'createdb', 'foobar1' ],
'fails if database already exists');
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 7396ff10c4..938432e8a4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -23,9 +23,9 @@
descr => 'standard POSIX collation',
collname => 'POSIX', collprovider => 'c', collencoding => '-1',
collcollate => 'POSIX', collctype => 'POSIX' },
-{ oid => '962', descr => 'sorts by Unicode code point',
- collname => 'ucs_basic', collprovider => 'c', collencoding => '6',
- collcollate => 'C', collctype => 'C' },
+{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',
+ collname => 'ucs_basic', collprovider => 'b', collencoding => '6',
+ colllocale => 'C' },
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index a3e196fb53..5ce289d74b 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -68,6 +68,7 @@ MAKE_SYSCACHE(COLLOID, pg_collation_oid_index, 8);
#ifdef EXPOSE_TO_CLIENT_CODE
#define COLLPROVIDER_DEFAULT 'd'
+#define COLLPROVIDER_BUILTIN 'b'
#define COLLPROVIDER_ICU 'i'
#define COLLPROVIDER_LIBC 'c'
@@ -76,6 +77,8 @@ collprovider_name(char c)
{
switch (c)
{
+ case COLLPROVIDER_BUILTIN:
+ return "builtin";
case COLLPROVIDER_ICU:
return "icu";
case COLLPROVIDER_LIBC:
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 28c925b5af..2348f56b6f 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -76,6 +76,14 @@ struct pg_locale_struct
bool deterministic;
union
{
+ struct
+ {
+ const char *locale;
+ bool casemap_full;
+ bool adjust_to_cased;
+ bool titlecase;
+ bool properties_posix;
+ } builtin;
locale_t lt;
#ifdef USE_ICU
struct
@@ -112,7 +120,7 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
pg_locale_t locale);
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
size_t srclen, pg_locale_t locale);
-
+extern const char *builtin_validate_locale(int encoding, const char *loc_str);
extern void icu_validate_locale(const char *loc_str);
extern char *icu_language_tag(const char *loc_str, int elevel);
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
index 8a1fc12ec6..5f8ef16803 100644
--- a/src/test/icu/t/010_database.pl
+++ b/src/test/icu/t/010_database.pl
@@ -27,9 +27,8 @@ CREATE TABLE icu (def text, en text COLLATE "en-x-icu", upfirst text COLLATE upp
INSERT INTO icu VALUES ('a', 'a', 'a'), ('b', 'b', 'b'), ('A', 'A', 'A'), ('B', 'B', 'B');
});
-is( $node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
- qq(t),
- 'ICU unicode version defined');
+is($node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
+ qq(t), 'ICU unicode version defined');
is( $node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY def}),
qq(A
@@ -63,14 +62,13 @@ is( $node1->psql(
0,
"C locale works for ICU");
-# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
-# are specified
-is( $node1->psql(
- 'postgres',
- q{CREATE DATABASE dbicu2 LOCALE_PROVIDER icu LOCALE '@colStrength=primary'
- LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0 ENCODING UTF8}
- ),
- 0,
- "LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE are specified");
+my ($ret, $stdout, $stderr) = $node1->psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
+);
+isnt($ret, 0, "locale provider must match template: exit code not 0");
+like(
+ $stderr,
+ qr/ERROR: new locale provider \(builtin\) does not match locale provider of the template database \(icu\)/,
+ "locale provider must match template: error message");
done_testing();
diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out
index 0649564485..ece4a8e99d 100644
--- a/src/test/regress/expected/collate.out
+++ b/src/test/regress/expected/collate.out
@@ -650,6 +650,26 @@ EXPLAIN (COSTS OFF)
(3 rows)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+ b
+-----
+ ABD
+ Abc
+ abc
+ bbc
+(4 rows)
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+ERROR: invalid locale name "en_US" for builtin provider
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+ERROR: conflicting or redundant options
+DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
@@ -754,7 +774,7 @@ DETAIL: FROM cannot be specified together with any other options.
-- must get rid of them.
--
DROP SCHEMA collate_tests CASCADE;
-NOTICE: drop cascades to 19 other objects
+NOTICE: drop cascades to 21 other objects
DETAIL: drop cascades to table collate_test1
drop cascades to table collate_test_like
drop cascades to table collate_test2
@@ -771,6 +791,8 @@ drop cascades to function dup(anyelement)
drop cascades to table collate_test20
drop cascades to table collate_test21
drop cascades to table collate_test22
+drop cascades to collation builtin_c
+drop cascades to collation builtin_posix
drop cascades to collation mycoll2
drop cascades to table collate_test23
drop cascades to view collate_on_int
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
new file mode 100644
index 0000000000..7535df9024
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8.out
@@ -0,0 +1,288 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+SET client_encoding TO UTF8;
+--
+-- Test builtin PG_UNICODE_FAST locale.
+--
+CREATE COLLATION BUILTIN_UNICODE_FAST
+ ( provider = builtin, locale = 'PG_UNICODE_FAST' );
+CREATE TABLE builtin_test1 (
+ t TEXT COLLATE BUILTIN_UNICODE_FAST
+);
+INSERT INTO builtin_test1 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test1;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123Abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE builtin_test1;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
+DROP COLLATION BUILTIN_UNICODE_FAST;
+--
+-- Test builtin C.UTF-8 locale.
+--
+CREATE COLLATION BUILTIN_C_UTF8 ( provider = builtin, locale = 'C.UTF-8' );
+CREATE TABLE builtin_test2 (
+ t TEXT COLLATE BUILTIN_C_UTF8
+);
+INSERT INTO builtin_test2 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test2;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+-----------------+-----------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs ßss Déf | ÁBC SßS ßSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | DŽxxdž DŽxxdž DŽxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE builtin_test2;
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ ασ
+(1 row)
+
+SELECT lower('ΑͺΣͺ' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ αͺσͺ
+(1 row)
+
+SELECT lower('Α΄Σ΄' COLLATE BUILTIN_C_UTF8);
+ lower
+-------
+ α΄σ΄
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' ~ '[[:punct:]]' COLLATE BUILTIN_C_UTF8; -- symbols are punctuation in posix
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' !~ '\d' COLLATE BUILTIN_C_UTF8; -- only 0-9 considered digits in posix
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_C_UTF8; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
+DROP COLLATION BUILTIN_C_UTF8;
diff --git a/src/test/regress/expected/collate.utf8_1.out b/src/test/regress/expected/collate.utf8_1.out
new file mode 100644
index 0000000000..e73fdf50c3
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8_1.out
@@ -0,0 +1,8 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 1d8a414eea..e48cb4b7a3 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,9 +78,9 @@ test: brin_bloom brin_multi
# psql depends on create_am
# amutils depends on geometry, create_index_spgist, hash_index, brin
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps
-# collate.*.utf8 tests cannot be run in parallel with each other
+# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252
# ----------
diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql
index c3d40fc195..01d5c69fe4 100644
--- a/src/test/regress/sql/collate.sql
+++ b/src/test/regress/sql/collate.sql
@@ -244,6 +244,16 @@ EXPLAIN (COSTS OFF)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
new file mode 100644
index 0000000000..ba92dcb7d2
--- /dev/null
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -0,0 +1,123 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+SET client_encoding TO UTF8;
+
+--
+-- Test builtin PG_UNICODE_FAST locale.
+--
+
+CREATE COLLATION BUILTIN_UNICODE_FAST
+ ( provider = builtin, locale = 'PG_UNICODE_FAST' );
+
+CREATE TABLE builtin_test1 (
+ t TEXT COLLATE BUILTIN_UNICODE_FAST
+);
+INSERT INTO builtin_test1 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test1;
+
+DROP TABLE builtin_test1;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
+
+DROP COLLATION BUILTIN_UNICODE_FAST;
+
+--
+-- Test builtin C.UTF-8 locale.
+--
+
+CREATE COLLATION BUILTIN_C_UTF8 ( provider = builtin, locale = 'C.UTF-8' );
+
+CREATE TABLE builtin_test2 (
+ t TEXT COLLATE BUILTIN_C_UTF8
+);
+INSERT INTO builtin_test2 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM builtin_test2;
+
+DROP TABLE builtin_test2;
+
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE BUILTIN_C_UTF8);
+SELECT lower('ΑͺΣͺ' COLLATE BUILTIN_C_UTF8);
+SELECT lower('Α΄Σ΄' COLLATE BUILTIN_C_UTF8);
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '=' ~ '[[:punct:]]' COLLATE BUILTIN_C_UTF8; -- symbols are punctuation in posix
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_C_UTF8;
+SELECT '൧' !~ '\d' COLLATE BUILTIN_C_UTF8; -- only 0-9 considered digits in posix
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_C_UTF8;
+SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_C_UTF8;
+SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_C_UTF8;
+SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_C_UTF8;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_C_UTF8; -- same as above with cases reversed
+
+DROP COLLATION BUILTIN_C_UTF8;
--
2.34.1
[text/x-patch] v20-0005-Add-builtin-collation-objects-PG_C_UTF8-and-PG_U.patch (10.8K, ../../[email protected]/6-v20-0005-Add-builtin-collation-objects-PG_C_UTF8-and-PG_U.patch)
download | inline diff:
From c50a9a7c58ea434406ba8e6240476885417b713f Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 19 Feb 2024 14:43:15 -0800
Subject: [PATCH v20 5/6] Add builtin collation objects PG_C_UTF8 and
PG_UNICODE_FAST.
---
doc/src/sgml/charset.sgml | 34 ++++++++++++++++
src/include/catalog/pg_collation.dat | 6 +++
src/test/regress/expected/collate.utf8.out | 45 ++++++++++-----------
src/test/regress/sql/collate.utf8.sql | 47 ++++++++++------------
4 files changed, 82 insertions(+), 50 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 7fe4a9bc39..9879260782 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -876,6 +876,40 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_unicode_fast</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. It is only
+ available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>pg_c_utf8</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function>, it uses
+ Unicode simple case mapping. For pattern matching (including regular
+ expressions), it uses the POSIX Compatible variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. This collation is
+ only available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
<listitem>
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 938432e8a4..a187b3dcef 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -30,5 +30,11 @@
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
+{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
+ collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
+ colllocale => 'C.UTF-8' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST' },
]
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index 7535df9024..5cafc89f3d 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -11,10 +11,8 @@ SET client_encoding TO UTF8;
--
-- Test builtin PG_UNICODE_FAST locale.
--
-CREATE COLLATION BUILTIN_UNICODE_FAST
- ( provider = builtin, locale = 'PG_UNICODE_FAST' );
CREATE TABLE builtin_test1 (
- t TEXT COLLATE BUILTIN_UNICODE_FAST
+ t TEXT COLLATE PG_UNICODE_FAST
);
INSERT INTO builtin_test1 VALUES
('abc DEF 123abc'),
@@ -42,130 +40,129 @@ SELECT
DROP TABLE builtin_test1;
-- test Final_Sigma
-SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
lower
-------
ας
(1 row)
-SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
lower
-------
ας0
(1 row)
-SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
lower
-------
ἀς̓
(1 row)
-SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
lower
-------
ᾳςͅ
(1 row)
-- test !Final_Sigma
-SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
lower
-------
σ
(1 row)
-SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
lower
-------
0σ
(1 row)
-SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
lower
-------
ασα
(1 row)
-SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
lower
-------
ἀσ̓α
(1 row)
-SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
lower
-------
ᾳσͅα
(1 row)
-- properties
-SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
?column?
----------
t
(1 row)
-SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-- case mapping
-SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_UNICODE_FAST;
?column?
----------
t
(1 row)
-SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
?column?
----------
t
(1 row)
-DROP COLLATION BUILTIN_UNICODE_FAST;
--
-- Test builtin C.UTF-8 locale.
--
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index ba92dcb7d2..19886734d3 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -15,11 +15,8 @@ SET client_encoding TO UTF8;
-- Test builtin PG_UNICODE_FAST locale.
--
-CREATE COLLATION BUILTIN_UNICODE_FAST
- ( provider = builtin, locale = 'PG_UNICODE_FAST' );
-
CREATE TABLE builtin_test1 (
- t TEXT COLLATE BUILTIN_UNICODE_FAST
+ t TEXT COLLATE PG_UNICODE_FAST
);
INSERT INTO builtin_test1 VALUES
('abc DEF 123abc'),
@@ -40,36 +37,34 @@ SELECT
DROP TABLE builtin_test1;
-- test Final_Sigma
-SELECT lower('ΑΣ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3
-SELECT lower('ΑΣ0' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0030
-SELECT lower('ἈΣ̓' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343
-SELECT lower('ᾼΣͅ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
-- test !Final_Sigma
-SELECT lower('Σ' COLLATE BUILTIN_UNICODE_FAST); -- 03A3
-SELECT lower('0Σ' COLLATE BUILTIN_UNICODE_FAST); -- 0030 03A3
-SELECT lower('ΑΣΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 03A3 0391
-SELECT lower('ἈΣ̓Α' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
-SELECT lower('ᾼΣͅΑ' COLLATE BUILTIN_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
-- properties
-SELECT 'xyz' ~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'xyz' !~ '[[:upper:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT '@' !~ '[[:alnum:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT '=' !~ '[[:punct:]]' COLLATE BUILTIN_UNICODE_FAST; -- symbols are not punctuation
-SELECT 'a8a' ~ '[[:digit:]]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT '൧' ~ '\d' COLLATE BUILTIN_UNICODE_FAST;
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
-- case mapping
-SELECT 'xYz' ~* 'XyZ' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'xAb' ~* '[W-Y]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'xAb' !~* '[c-d]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'Δ' ~* '[α-λ]' COLLATE BUILTIN_UNICODE_FAST;
-SELECT 'δ' ~* '[Γ-Λ]' COLLATE BUILTIN_UNICODE_FAST; -- same as above with cases reversed
-
-DROP COLLATION BUILTIN_UNICODE_FAST;
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
-- Test builtin C.UTF-8 locale.
--
2.34.1
[text/x-patch] v20-0006-Inline-basic-UTF-8-functions.patch (6.2K, ../../[email protected]/7-v20-0006-Inline-basic-UTF-8-functions.patch)
download | inline diff:
From f7a7f21ce173fb149c9d1fbaa4ac13a5c0b9bf6d Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 2 Mar 2024 11:27:23 -0800
Subject: [PATCH v20 6/6] Inline basic UTF-8 functions.
Shows a measurable speedup when processing UTF-8 data, such as with
the new builtin collation provider.
---
src/common/wchar.c | 92 +------------------------------------
src/include/mb/pg_wchar.h | 96 +++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 91 deletions(-)
diff --git a/src/common/wchar.c b/src/common/wchar.c
index a238c0106c..17788ac8b8 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -476,39 +476,6 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
}
-/*
- * Map a Unicode code point to UTF-8. utf8string must have at least
- * unicode_utf8len(c) bytes available.
- */
-unsigned char *
-unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
-{
- if (c <= 0x7F)
- {
- utf8string[0] = c;
- }
- else if (c <= 0x7FF)
- {
- utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
- utf8string[1] = 0x80 | (c & 0x3F);
- }
- else if (c <= 0xFFFF)
- {
- utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
- utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[2] = 0x80 | (c & 0x3F);
- }
- else
- {
- utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
- utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
- utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[3] = 0x80 | (c & 0x3F);
- }
-
- return utf8string;
-}
-
/*
* Trivial conversion from pg_wchar to UTF-8.
* caller should allocate enough space for "to"
@@ -535,39 +502,10 @@ pg_wchar2utf_with_len(const pg_wchar *from, unsigned char *to, int len)
return cnt;
}
-/*
- * Return the byte length of a UTF8 character pointed to by s
- *
- * Note: in the current implementation we do not support UTF8 sequences
- * of more than 4 bytes; hence do NOT return a value larger than 4.
- * We return "1" for any leading byte that is either flat-out illegal or
- * indicates a length larger than we support.
- *
- * pg_utf2wchar_with_len(), utf8_to_unicode(), pg_utf8_islegal(), and perhaps
- * other places would need to be fixed to change this.
- */
int
pg_utf_mblen(const unsigned char *s)
{
- int len;
-
- if ((*s & 0x80) == 0)
- len = 1;
- else if ((*s & 0xe0) == 0xc0)
- len = 2;
- else if ((*s & 0xf0) == 0xe0)
- len = 3;
- else if ((*s & 0xf8) == 0xf0)
- len = 4;
-#ifdef NOT_USED
- else if ((*s & 0xfc) == 0xf8)
- len = 5;
- else if ((*s & 0xfe) == 0xfc)
- len = 6;
-#endif
- else
- len = 1;
- return len;
+ return utf8_mblen(s);
}
/*
@@ -670,34 +608,6 @@ ucs_wcwidth(pg_wchar ucs)
return 1;
}
-/*
- * Convert a UTF-8 character to a Unicode code point.
- * This is a one-character version of pg_utf2wchar_with_len.
- *
- * No error checks here, c must point to a long-enough string.
- */
-pg_wchar
-utf8_to_unicode(const unsigned char *c)
-{
- if ((*c & 0x80) == 0)
- return (pg_wchar) c[0];
- else if ((*c & 0xe0) == 0xc0)
- return (pg_wchar) (((c[0] & 0x1f) << 6) |
- (c[1] & 0x3f));
- else if ((*c & 0xf0) == 0xe0)
- return (pg_wchar) (((c[0] & 0x0f) << 12) |
- ((c[1] & 0x3f) << 6) |
- (c[2] & 0x3f));
- else if ((*c & 0xf8) == 0xf0)
- return (pg_wchar) (((c[0] & 0x07) << 18) |
- ((c[1] & 0x3f) << 12) |
- ((c[2] & 0x3f) << 6) |
- (c[3] & 0x3f));
- else
- /* that is an invalid code on purpose */
- return 0xffffffff;
-}
-
static int
pg_utf_dsplen(const unsigned char *s)
{
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 69a55b66f4..f0ce47977c 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -555,6 +555,102 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Return the byte length of a UTF8 character pointed to by s
+ *
+ * Note: in the current implementation we do not support UTF8 sequences
+ * of more than 4 bytes; hence do NOT return a value larger than 4.
+ * We return "1" for any leading byte that is either flat-out illegal or
+ * indicates a length larger than we support.
+ *
+ * pg_utf2wchar_with_len(), utf8_to_unicode(), pg_utf8_islegal(), and perhaps
+ * other places would need to be fixed to change this.
+ */
+static inline int
+utf8_mblen(const unsigned char *s)
+{
+ int len;
+
+ if ((*s & 0x80) == 0)
+ len = 1;
+ else if ((*s & 0xe0) == 0xc0)
+ len = 2;
+ else if ((*s & 0xf0) == 0xe0)
+ len = 3;
+ else if ((*s & 0xf8) == 0xf0)
+ len = 4;
+#ifdef NOT_USED
+ else if ((*s & 0xfc) == 0xf8)
+ len = 5;
+ else if ((*s & 0xfe) == 0xfc)
+ len = 6;
+#endif
+ else
+ len = 1;
+ return len;
+}
+
+/*
+ * Convert a UTF-8 character to a Unicode code point.
+ * This is a one-character version of pg_utf2wchar_with_len.
+ *
+ * No error checks here, c must point to a long-enough string.
+ */
+static inline pg_wchar
+utf8_to_unicode(const unsigned char *c)
+{
+ if ((*c & 0x80) == 0)
+ return (pg_wchar) c[0];
+ else if ((*c & 0xe0) == 0xc0)
+ return (pg_wchar) (((c[0] & 0x1f) << 6) |
+ (c[1] & 0x3f));
+ else if ((*c & 0xf0) == 0xe0)
+ return (pg_wchar) (((c[0] & 0x0f) << 12) |
+ ((c[1] & 0x3f) << 6) |
+ (c[2] & 0x3f));
+ else if ((*c & 0xf8) == 0xf0)
+ return (pg_wchar) (((c[0] & 0x07) << 18) |
+ ((c[1] & 0x3f) << 12) |
+ ((c[2] & 0x3f) << 6) |
+ (c[3] & 0x3f));
+ else
+ /* that is an invalid code on purpose */
+ return 0xffffffff;
+}
+
+/*
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
+ */
+static inline unsigned char *
+unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
+{
+ if (c <= 0x7F)
+ {
+ utf8string[0] = c;
+ }
+ else if (c <= 0x7FF)
+ {
+ utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
+ utf8string[1] = 0x80 | (c & 0x3F);
+ }
+ else if (c <= 0xFFFF)
+ {
+ utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
+ utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[2] = 0x80 | (c & 0x3F);
+ }
+ else
+ {
+ utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
+ utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
+ utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[3] = 0x80 | (c & 0x3F);
+ }
+
+ return utf8string;
+}
+
/*
* Number of bytes needed to represent the given char in UTF8.
*/
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-08 01:00 ` Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-08 01:00 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Sat, 2024-03-02 at 15:02 -0800, Jeff Davis wrote:
> Attached v20.
And here's v22 (I didn't post v21).
I committed Unicode property tables and functions, and the simple case
mapping. I separated out the full case mapping changes (based on
SpecialCasing.txt) into patch 0006.
Not a lot of technical changes, but I cleaned up the remaining patches
and put them into a nicer order with nicer commit messages.
0001: Catalog renaming: colliculocale to colllocale and daticulocale to
datlocale.
0002: Basic builtin collation provider that only supports "C".
0003: C.UTF-8 locale for builtin collation provider and collation
pg_c_utf8.
0004: Inline some UTF-8 functions to improve performance
0005: Add a unicode_strtitle() function and move the implementation for
the builtin provider out of formatting.c.
0006: Add full case mapping support
0007: Add PG_UNICODE_FAST locale for builtin collation provider and
collation pg_unicode_fast. This behaves like the standard says
UCS_BASIC should behave -- sort by code point order but use Unicode
character semantics with full case mapping.
0004 and beyond could use some review. 0004 and 0005 are pretty simple
and non-controversial. 0006 and 0007 are a bit more interesting and
could use some discussion if we want to go ahead with full case mapping
in 17.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v22-0001-Catalog-changes-preparing-for-builtin-collation-.patch (48.8K, ../../[email protected]/2-v22-0001-Catalog-changes-preparing-for-builtin-collation-.patch)
download | inline diff:
From 039e71a7908f7e0e9302e7ab43c1025ab826274c Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Tue, 26 Dec 2023 13:32:48 -0800
Subject: [PATCH v22 1/7] Catalog changes preparing for builtin collation
provider.
Rename pg_collation.colliculocale to colllocale, and
pg_database.daticulocale to datlocale. This reflects that the fields
will be useful for the builtin provider as well, not just for ICU.
This is purely a rename; no changes to the meaning of the fields.
Discussion: https://postgr.es/m/ff4c2f2f9c8fc7ca27c1c24ae37ecaeaeaff6b53.camel%40j-davis.com
Reviewed-by: Peter Eisentraut
---
doc/src/sgml/bki.sgml | 2 +-
doc/src/sgml/catalogs.sgml | 8 +--
src/backend/catalog/pg_collation.c | 10 +--
src/backend/commands/collationcmds.c | 34 +++++-----
src/backend/commands/dbcommands.c | 68 +++++++++----------
src/backend/utils/adt/pg_locale.c | 4 +-
src/backend/utils/init/postinit.c | 12 ++--
src/bin/initdb/initdb.c | 32 ++++-----
src/bin/pg_dump/pg_dump.c | 56 ++++++++-------
src/bin/pg_upgrade/info.c | 31 ++++++---
src/bin/pg_upgrade/pg_upgrade.c | 34 +++++++---
src/bin/pg_upgrade/pg_upgrade.h | 2 +-
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 27 +++++---
src/bin/psql/describe.c | 20 ++++--
src/include/catalog/pg_collation.dat | 2 +-
src/include/catalog/pg_collation.h | 4 +-
src/include/catalog/pg_database.dat | 2 +-
src/include/catalog/pg_database.h | 2 +-
.../regress/expected/collate.icu.utf8.out | 4 +-
src/test/regress/expected/psql.out | 18 ++---
src/test/regress/sql/collate.icu.utf8.sql | 4 +-
21 files changed, 211 insertions(+), 165 deletions(-)
diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 315ba81951..3cd5bee7ff 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -186,7 +186,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE', datacl => '_null_' },
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE', datacl => '_null_' },
]
]]></programlisting>
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 0ae97d1ada..fb48a5a745 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2422,10 +2422,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>colliculocale</structfield> <type>text</type>
+ <structfield>colllocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this collation object
+ Locale name for builtin or ICU provider
</para></entry>
</row>
@@ -3131,10 +3131,10 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
- <structfield>daticulocale</structfield> <type>text</type>
+ <structfield>datlocale</structfield> <type>text</type>
</para>
<para>
- ICU locale ID for this database
+ Locale name for builtin or ICU provider
</para></entry>
</row>
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 7bce19bd83..e42f2afccb 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -45,7 +45,7 @@ CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
@@ -64,7 +64,7 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colliculocale);
+ Assert((collcollate && collctype) || colllocale);
/*
* Make sure there is no existing collation of same name & encoding.
@@ -187,10 +187,10 @@ CollationCreate(const char *collname, Oid collnamespace,
values[Anum_pg_collation_collctype - 1] = CStringGetTextDatum(collctype);
else
nulls[Anum_pg_collation_collctype - 1] = true;
- if (colliculocale)
- values[Anum_pg_collation_colliculocale - 1] = CStringGetTextDatum(colliculocale);
+ if (colllocale)
+ values[Anum_pg_collation_colllocale - 1] = CStringGetTextDatum(colllocale);
else
- nulls[Anum_pg_collation_colliculocale - 1] = true;
+ nulls[Anum_pg_collation_colllocale - 1] = true;
if (collicurules)
values[Anum_pg_collation_collicurules - 1] = CStringGetTextDatum(collicurules);
else
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 106e696da8..59d7e17804 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -66,7 +66,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colliculocale;
+ char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -157,11 +157,11 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
else
collctype = NULL;
- datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colliculocale, &isnull);
+ datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colllocale, &isnull);
if (!isnull)
- colliculocale = TextDatumGetCString(datum);
+ colllocale = TextDatumGetCString(datum);
else
- colliculocale = NULL;
+ colllocale = NULL;
/*
* When the ICU locale comes from an existing collation, do not
@@ -194,7 +194,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collcollate = NULL;
collctype = NULL;
- colliculocale = NULL;
+ colllocale = NULL;
collicurules = NULL;
if (providerEl)
@@ -234,7 +234,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collctype = defGetString(localeEl);
}
else
- colliculocale = defGetString(localeEl);
+ colllocale = defGetString(localeEl);
}
if (lccollateEl)
@@ -259,7 +259,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
else if (collprovider == COLLPROVIDER_ICU)
{
- if (!colliculocale)
+ if (!colllocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("parameter \"%s\" must be specified",
@@ -271,20 +271,20 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
*/
if (!IsBinaryUpgrade)
{
- char *langtag = icu_language_tag(colliculocale,
+ char *langtag = icu_language_tag(colllocale,
icu_validation_level);
- if (langtag && strcmp(colliculocale, langtag) != 0)
+ if (langtag && strcmp(colllocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, colliculocale)));
+ langtag, colllocale)));
- colliculocale = langtag;
+ colllocale = langtag;
}
}
- icu_validate_locale(colliculocale);
+ icu_validate_locale(colllocale);
}
/*
@@ -332,7 +332,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colliculocale : collcollate);
+ collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
newoid = CollationCreate(collName,
collNamespace,
@@ -342,7 +342,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collencoding,
collcollate,
collctype,
- colliculocale,
+ colllocale,
collicurules,
collversion,
if_not_exists,
@@ -433,7 +433,7 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
/* cannot change from NULL to non-NULL or vice versa */
@@ -500,7 +500,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
provider == COLLPROVIDER_ICU ?
- Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ Anum_pg_database_datlocale : Anum_pg_database_datcollate);
locale = TextDatumGetCString(datum);
@@ -521,7 +521,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
Assert(provider != COLLPROVIDER_DEFAULT);
datum = SysCacheGetAttrNotNull(COLLOID, colltp,
provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
locale = TextDatumGetCString(datum);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index b256d6d0f7..0f27d7b14c 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -117,7 +117,7 @@ static bool get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion);
@@ -674,7 +674,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
int src_encoding = -1;
char *src_collate = NULL;
char *src_ctype = NULL;
- char *src_iculocale = NULL;
+ char *src_locale = NULL;
char *src_icurules = NULL;
char src_locprovider = '\0';
char *src_collversion = NULL;
@@ -712,7 +712,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dbiculocale = NULL;
+ char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -902,7 +902,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (dctype && dctype->arg)
dbctype = defGetString(dctype);
if (diculocale && diculocale->arg)
- dbiculocale = defGetString(diculocale);
+ dblocale = defGetString(diculocale);
if (dicurules && dicurules->arg)
dbicurules = defGetString(dicurules);
if (dlocprovider && dlocprovider->arg)
@@ -970,7 +970,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
&src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_allowconn, &src_hasloginevt,
&src_frozenxid, &src_minmxid, &src_deftablespace,
- &src_collate, &src_ctype, &src_iculocale, &src_icurules, &src_locprovider,
+ &src_collate, &src_ctype, &src_locale, &src_icurules, &src_locprovider,
&src_collversion))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
@@ -1026,12 +1026,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dbiculocale == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
{
if (dlocale && dlocale->arg)
- dbiculocale = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
else
- dbiculocale = src_iculocale;
+ dblocale = src_locale;
}
if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
dbicurules = src_icurules;
@@ -1070,7 +1070,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* This would happen if template0 uses the libc provider but the new
* database uses icu.
*/
- if (!dbiculocale)
+ if (!dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("LOCALE or ICU_LOCALE must be specified")));
@@ -1080,26 +1080,26 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* database, preserve locale string. Otherwise, canonicalize to a
* language tag.
*/
- if (!IsBinaryUpgrade && dbiculocale != src_iculocale)
+ if (!IsBinaryUpgrade && dblocale != src_locale)
{
- char *langtag = icu_language_tag(dbiculocale,
+ char *langtag = icu_language_tag(dblocale,
icu_validation_level);
- if (langtag && strcmp(dbiculocale, langtag) != 0)
+ if (langtag && strcmp(dblocale, langtag) != 0)
{
ereport(NOTICE,
(errmsg("using standard form \"%s\" for ICU locale \"%s\"",
- langtag, dbiculocale)));
+ langtag, dblocale)));
- dbiculocale = langtag;
+ dblocale = langtag;
}
}
- icu_validate_locale(dbiculocale);
+ icu_validate_locale(dblocale);
}
else
{
- if (dbiculocale)
+ if (dblocale)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1156,13 +1156,13 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
char *val1;
char *val2;
- Assert(dbiculocale);
- Assert(src_iculocale);
- if (strcmp(dbiculocale, src_iculocale) != 0)
+ Assert(dblocale);
+ Assert(src_locale);
+ if (strcmp(dblocale, src_locale) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("new ICU locale (%s) is incompatible with the ICU locale of the template database (%s)",
- dbiculocale, src_iculocale),
+ dblocale, src_locale),
errhint("Use the same ICU locale as in the template database, or use template0 as template.")));
val1 = dbicurules;
@@ -1196,7 +1196,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *actual_versionstr;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1224,7 +1224,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dbiculocale : dbcollate);
+ dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1363,8 +1363,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dbiculocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dbiculocale));
+ Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
+ (dblocprovider != COLLPROVIDER_ICU && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -1382,10 +1382,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);
new_record[Anum_pg_database_datcollate - 1] = CStringGetTextDatum(dbcollate);
new_record[Anum_pg_database_datctype - 1] = CStringGetTextDatum(dbctype);
- if (dbiculocale)
- new_record[Anum_pg_database_daticulocale - 1] = CStringGetTextDatum(dbiculocale);
+ if (dblocale)
+ new_record[Anum_pg_database_datlocale - 1] = CStringGetTextDatum(dblocale);
else
- new_record_nulls[Anum_pg_database_daticulocale - 1] = true;
+ new_record_nulls[Anum_pg_database_datlocale - 1] = true;
if (dbicurules)
new_record[Anum_pg_database_daticurules - 1] = CStringGetTextDatum(dbicurules);
else
@@ -2471,7 +2471,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
if (isnull)
elog(ERROR, "unexpected null in pg_database");
newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
@@ -2669,7 +2669,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_daticulocale : Anum_pg_database_datcollate);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
ReleaseSysCache(tp);
@@ -2696,7 +2696,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,
TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP,
- Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbIculocale,
+ Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,
char **dbIcurules,
char *dbLocProvider,
char **dbCollversion)
@@ -2807,13 +2807,13 @@ get_db_info(const char *name, LOCKMODE lockmode,
datum = SysCacheGetAttrNotNull(DATABASEOID, tuple, Anum_pg_database_datctype);
*dbCtype = TextDatumGetCString(datum);
}
- if (dbIculocale)
+ if (dbLocale)
{
- datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_daticulocale, &isnull);
+ datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datlocale, &isnull);
if (isnull)
- *dbIculocale = NULL;
+ *dbLocale = NULL;
else
- *dbIculocale = TextDatumGetCString(datum);
+ *dbLocale = TextDatumGetCString(datum);
}
if (dbIcurules)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 8e6822ee59..77d5752dc8 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1605,7 +1605,7 @@ pg_newlocale_from_collation(Oid collid)
const char *iculocstr;
const char *icurules;
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colliculocale);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
iculocstr = TextDatumGetCString(datum);
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
@@ -1626,7 +1626,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colliculocale : Anum_pg_collation_collcollate);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
TextDatumGetCString(datum));
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 16f3659fd9..2875bc97d3 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -318,7 +318,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
bool isnull;
char *collate;
char *ctype;
- char *iculocale;
+ char *datlocale;
/* Fetch our pg_database row normally, via syscache */
tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
@@ -427,8 +427,8 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *icurules;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_daticulocale);
- iculocale = TextDatumGetCString(datum);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_daticurules, &isnull);
if (!isnull)
@@ -436,10 +436,10 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
else
icurules = NULL;
- make_icu_collator(iculocale, icurules, &default_locale);
+ make_icu_collator(datlocale, icurules, &default_locale);
}
else
- iculocale = NULL;
+ datlocale = NULL;
default_locale.provider = dbform->datlocprovider;
@@ -464,7 +464,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? iculocale : collate);
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 200b2e8e31..4d78155759 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -145,7 +145,7 @@ static char *lc_numeric = NULL;
static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
-static char *icu_locale = NULL;
+static char *datlocale = NULL;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -1520,8 +1520,8 @@ bootstrap_template1(void)
bki_lines = replace_token(bki_lines, "LC_CTYPE",
escape_quotes_bki(lc_ctype));
- bki_lines = replace_token(bki_lines, "ICU_LOCALE",
- icu_locale ? escape_quotes_bki(icu_locale) : "_null_");
+ bki_lines = replace_token(bki_lines, "DATLOCALE",
+ datlocale ? escape_quotes_bki(datlocale) : "_null_");
bki_lines = replace_token(bki_lines, "ICU_RULES",
icu_rules ? escape_quotes_bki(icu_rules) : "_null_");
@@ -2368,8 +2368,8 @@ setlocales(void)
lc_monetary = locale;
if (!lc_messages)
lc_messages = locale;
- if (!icu_locale && locale_provider == COLLPROVIDER_ICU)
- icu_locale = locale;
+ if (!datlocale && locale_provider != COLLPROVIDER_LIBC)
+ datlocale = locale;
}
/*
@@ -2400,17 +2400,17 @@ setlocales(void)
char *langtag;
/* acquire default locale from the environment, if not specified */
- if (icu_locale == NULL)
+ if (datlocale == NULL)
pg_fatal("ICU locale must be specified");
/* canonicalize to a language tag */
- langtag = icu_language_tag(icu_locale);
+ langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
- langtag, icu_locale);
- pg_free(icu_locale);
- icu_locale = langtag;
+ langtag, datlocale);
+ pg_free(datlocale);
+ datlocale = langtag;
- icu_validate_locale(icu_locale);
+ icu_validate_locale(datlocale);
/*
* In supported builds, the ICU locale ID will be opened during
@@ -2604,14 +2604,14 @@ setup_locale_encoding(void)
strcmp(lc_ctype, lc_numeric) == 0 &&
strcmp(lc_ctype, lc_monetary) == 0 &&
strcmp(lc_ctype, lc_messages) == 0 &&
- (!icu_locale || strcmp(lc_ctype, icu_locale) == 0))
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (icu_locale)
- printf(_(" ICU locale: %s\n"), icu_locale);
+ if (datlocale)
+ printf(_(" ICU locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3282,7 +3282,7 @@ main(int argc, char *argv[])
pg_fatal("unrecognized locale provider: %s", optarg);
break;
case 16:
- icu_locale = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
break;
case 17:
icu_rules = pg_strdup(optarg);
@@ -3317,7 +3317,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (icu_locale && locale_provider != COLLPROVIDER_ICU)
+ if (datlocale && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 10cbf02beb..23e6217b73 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2984,7 +2984,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider,
i_collate,
i_ctype,
- i_daticulocale,
+ i_datlocale,
i_daticurules,
i_frozenxid,
i_minmxid,
@@ -3003,7 +3003,7 @@ dumpDatabase(Archive *fout)
*datlocprovider,
*collate,
*ctype,
- *iculocale,
+ *locale,
*icurules,
*datistemplate,
*datconnlimit,
@@ -3027,10 +3027,12 @@ dumpDatabase(Archive *fout)
appendPQExpBufferStr(dbQry, "datminmxid, ");
else
appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
- if (fout->remoteVersion >= 150000)
- appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale, datcollversion, ");
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
+ else if (fout->remoteVersion >= 150000)
+ appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
else
- appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS daticulocale, NULL AS datcollversion, ");
+ appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(dbQry, "daticurules, ");
else
@@ -3051,7 +3053,7 @@ dumpDatabase(Archive *fout)
i_datlocprovider = PQfnumber(res, "datlocprovider");
i_collate = PQfnumber(res, "datcollate");
i_ctype = PQfnumber(res, "datctype");
- i_daticulocale = PQfnumber(res, "daticulocale");
+ i_datlocale = PQfnumber(res, "datlocale");
i_daticurules = PQfnumber(res, "daticurules");
i_frozenxid = PQfnumber(res, "datfrozenxid");
i_minmxid = PQfnumber(res, "datminmxid");
@@ -3070,10 +3072,10 @@ dumpDatabase(Archive *fout)
datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
collate = PQgetvalue(res, 0, i_collate);
ctype = PQgetvalue(res, 0, i_ctype);
- if (!PQgetisnull(res, 0, i_daticulocale))
- iculocale = PQgetvalue(res, 0, i_daticulocale);
+ if (!PQgetisnull(res, 0, i_datlocale))
+ locale = PQgetvalue(res, 0, i_datlocale);
else
- iculocale = NULL;
+ locale = NULL;
if (!PQgetisnull(res, 0, i_daticurules))
icurules = PQgetvalue(res, 0, i_daticurules);
else
@@ -3138,11 +3140,12 @@ dumpDatabase(Archive *fout)
appendStringLiteralAH(creaQry, ctype, fout);
}
}
- if (iculocale)
+ if (locale)
{
appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
- appendStringLiteralAH(creaQry, iculocale, fout);
+ appendStringLiteralAH(creaQry, locale, fout);
}
+
if (icurules)
{
appendPQExpBufferStr(creaQry, " ICU_RULES = ");
@@ -13756,12 +13759,12 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
int i_collisdeterministic;
int i_collcollate;
int i_collctype;
- int i_colliculocale;
+ int i_colllocale;
int i_collicurules;
const char *collprovider;
const char *collcollate;
const char *collctype;
- const char *colliculocale;
+ const char *colllocale;
const char *collicurules;
/* Do nothing in data-only dump */
@@ -13793,12 +13796,15 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
appendPQExpBufferStr(query,
"true AS collisdeterministic, ");
- if (fout->remoteVersion >= 150000)
+ if (fout->remoteVersion >= 170000)
+ appendPQExpBufferStr(query,
+ "colllocale, ");
+ else if (fout->remoteVersion >= 150000)
appendPQExpBufferStr(query,
- "colliculocale, ");
+ "colliculocale AS colllocale, ");
else
appendPQExpBufferStr(query,
- "NULL AS colliculocale, ");
+ "NULL AS colllocale, ");
if (fout->remoteVersion >= 160000)
appendPQExpBufferStr(query,
@@ -13820,7 +13826,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
i_collisdeterministic = PQfnumber(res, "collisdeterministic");
i_collcollate = PQfnumber(res, "collcollate");
i_collctype = PQfnumber(res, "collctype");
- i_colliculocale = PQfnumber(res, "colliculocale");
+ i_colllocale = PQfnumber(res, "colllocale");
i_collicurules = PQfnumber(res, "collicurules");
collprovider = PQgetvalue(res, 0, i_collprovider);
@@ -13847,10 +13853,10 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
collctype = NULL;
}
- if (!PQgetisnull(res, 0, i_colliculocale))
- colliculocale = PQgetvalue(res, 0, i_colliculocale);
+ if (!PQgetisnull(res, 0, i_colllocale))
+ colllocale = PQgetvalue(res, 0, i_colllocale);
else
- colliculocale = NULL;
+ colllocale = NULL;
if (!PQgetisnull(res, 0, i_collicurules))
collicurules = PQgetvalue(res, 0, i_collicurules);
@@ -13880,7 +13886,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
if (collprovider[0] == 'd')
{
- if (collcollate || collctype || colliculocale || collicurules)
+ if (collcollate || collctype || colllocale || collicurules)
pg_log_warning("invalid collation \"%s\"", qcollname);
/* no locale -- the default collation cannot be reloaded anyway */
@@ -13889,16 +13895,16 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
{
if (fout->remoteVersion >= 150000)
{
- if (collcollate || collctype || !colliculocale)
+ if (collcollate || collctype || !colllocale)
pg_log_warning("invalid collation \"%s\"", qcollname);
appendPQExpBufferStr(q, ", locale = ");
- appendStringLiteralAH(q, colliculocale ? colliculocale : "",
+ appendStringLiteralAH(q, colllocale ? colllocale : "",
fout);
}
else
{
- if (!collcollate || !collctype || colliculocale ||
+ if (!collcollate || !collctype || colllocale ||
strcmp(collcollate, collctype) != 0)
pg_log_warning("invalid collation \"%s\"", qcollname);
@@ -13914,7 +13920,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
}
else if (collprovider[0] == 'c')
{
- if (colliculocale || collicurules || !collcollate || !collctype)
+ if (colllocale || collicurules || !collcollate || !collctype)
pg_log_warning("invalid collation \"%s\"", qcollname);
if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c
index 183c2f84eb..101fe855fc 100644
--- a/src/bin/pg_upgrade/info.c
+++ b/src/bin/pg_upgrade/info.c
@@ -328,18 +328,24 @@ get_template0_info(ClusterInfo *cluster)
int i_datlocprovider;
int i_datcollate;
int i_datctype;
- int i_daticulocale;
+ int i_datlocale;
- if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
dbres = executeQueryOrDie(conn,
"SELECT encoding, datlocprovider, "
- " datcollate, datctype, daticulocale "
+ " datcollate, datctype, datlocale "
+ "FROM pg_catalog.pg_database "
+ "WHERE datname='template0'");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
+ dbres = executeQueryOrDie(conn,
+ "SELECT encoding, datlocprovider, "
+ " datcollate, datctype, daticulocale AS datlocale"
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
else
dbres = executeQueryOrDie(conn,
"SELECT encoding, 'c' AS datlocprovider, "
- " datcollate, datctype, NULL AS daticulocale "
+ " datcollate, datctype, NULL AS datlocale "
"FROM pg_catalog.pg_database "
"WHERE datname='template0'");
@@ -353,16 +359,16 @@ get_template0_info(ClusterInfo *cluster)
i_datlocprovider = PQfnumber(dbres, "datlocprovider");
i_datcollate = PQfnumber(dbres, "datcollate");
i_datctype = PQfnumber(dbres, "datctype");
- i_daticulocale = PQfnumber(dbres, "daticulocale");
+ i_datlocale = PQfnumber(dbres, "datlocale");
locale->db_encoding = atoi(PQgetvalue(dbres, 0, i_datencoding));
locale->db_collprovider = PQgetvalue(dbres, 0, i_datlocprovider)[0];
locale->db_collate = pg_strdup(PQgetvalue(dbres, 0, i_datcollate));
locale->db_ctype = pg_strdup(PQgetvalue(dbres, 0, i_datctype));
- if (PQgetisnull(dbres, 0, i_daticulocale))
- locale->db_iculocale = NULL;
+ if (PQgetisnull(dbres, 0, i_datlocale))
+ locale->db_locale = NULL;
else
- locale->db_iculocale = pg_strdup(PQgetvalue(dbres, 0, i_daticulocale));
+ locale->db_locale = pg_strdup(PQgetvalue(dbres, 0, i_datlocale));
cluster->template0 = locale;
@@ -392,12 +398,15 @@ get_db_infos(ClusterInfo *cluster)
snprintf(query, sizeof(query),
"SELECT d.oid, d.datname, d.encoding, d.datcollate, d.datctype, ");
- if (GET_MAJOR_VERSION(cluster->major_version) < 1500)
+ if (GET_MAJOR_VERSION(cluster->major_version) >= 1700)
+ snprintf(query + strlen(query), sizeof(query) - strlen(query),
+ "datlocprovider, datlocale, ");
+ else if (GET_MAJOR_VERSION(cluster->major_version) >= 1500)
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "'c' AS datlocprovider, NULL AS daticulocale, ");
+ "datlocprovider, daticulocale AS datlocale, ");
else
snprintf(query + strlen(query), sizeof(query) - strlen(query),
- "datlocprovider, daticulocale, ");
+ "'c' AS datlocprovider, NULL AS datlocale, ");
snprintf(query + strlen(query), sizeof(query) - strlen(query),
"pg_catalog.pg_tablespace_location(t.oid) AS spclocation "
"FROM pg_catalog.pg_database d "
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 10c94a6c1f..bb261353bd 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -391,7 +391,7 @@ setup(char *argv0, bool *live_check)
* Copy locale and encoding information into the new cluster's template0.
*
* We need to copy the encoding, datlocprovider, datcollate, datctype, and
- * daticulocale. We don't need datcollversion because that's never set for
+ * datlocale. We don't need datcollversion because that's never set for
* template0.
*/
static void
@@ -400,7 +400,7 @@ set_locale_and_encoding(void)
PGconn *conn_new_template1;
char *datcollate_literal;
char *datctype_literal;
- char *daticulocale_literal = NULL;
+ char *datlocale_literal = NULL;
DbLocaleInfo *locale = old_cluster.template0;
prep_status("Setting locale and encoding for new cluster");
@@ -414,15 +414,29 @@ set_locale_and_encoding(void)
datctype_literal = PQescapeLiteral(conn_new_template1,
locale->db_ctype,
strlen(locale->db_ctype));
- if (locale->db_iculocale)
- daticulocale_literal = PQescapeLiteral(conn_new_template1,
- locale->db_iculocale,
- strlen(locale->db_iculocale));
+ if (locale->db_locale)
+ datlocale_literal = PQescapeLiteral(conn_new_template1,
+ locale->db_locale,
+ strlen(locale->db_locale));
else
- daticulocale_literal = pg_strdup("NULL");
+ datlocale_literal = pg_strdup("NULL");
/* update template0 in new cluster */
- if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
+ if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1700)
+ PQclear(executeQueryOrDie(conn_new_template1,
+ "UPDATE pg_catalog.pg_database "
+ " SET encoding = %d, "
+ " datlocprovider = '%c', "
+ " datcollate = %s, "
+ " datctype = %s, "
+ " datlocale = %s "
+ " WHERE datname = 'template0' ",
+ locale->db_encoding,
+ locale->db_collprovider,
+ datcollate_literal,
+ datctype_literal,
+ datlocale_literal));
+ else if (GET_MAJOR_VERSION(new_cluster.major_version) >= 1500)
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
" SET encoding = %d, "
@@ -435,7 +449,7 @@ set_locale_and_encoding(void)
locale->db_collprovider,
datcollate_literal,
datctype_literal,
- daticulocale_literal));
+ datlocale_literal));
else
PQclear(executeQueryOrDie(conn_new_template1,
"UPDATE pg_catalog.pg_database "
@@ -449,7 +463,7 @@ set_locale_and_encoding(void)
PQfreemem(datcollate_literal);
PQfreemem(datctype_literal);
- PQfreemem(daticulocale_literal);
+ PQfreemem(datlocale_literal);
PQfinish(conn_new_template1);
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index 857d715049..c0bfb002d2 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -208,7 +208,7 @@ typedef struct
char *db_collate;
char *db_ctype;
char db_collprovider;
- char *db_iculocale;
+ char *db_locale;
int db_encoding;
} DbLocaleInfo;
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index d951ed3af0..41d06d272b 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -104,6 +104,8 @@ if ($oldnode->pg_version >= 11)
push @custom_opts, '--allow-group-access';
}
+my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
+
# Set up the locale settings for the original cluster, so that we
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
@@ -111,15 +113,22 @@ if ($oldnode->pg_version >= 11)
my $original_encoding = "6"; # UTF-8
my $original_provider = "c";
my $original_locale = "C";
-my $original_iculocale = "";
+my $original_datlocale = "";
my $provider_field = "'c' AS datlocprovider";
-my $iculocale_field = "NULL AS daticulocale";
-if ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
+my $datlocale_field = "NULL AS datlocale";
+if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$provider_field = "datlocprovider";
- $iculocale_field = "daticulocale";
+ if ($oldversion >= 17)
+ {
+ $datlocale_field = "datlocale";
+ }
+ else
+ {
+ $datlocale_field = "daticulocale AS datlocale";
+ }
$original_provider = "i";
- $original_iculocale = "fr-CA";
+ $original_datlocale = "fr-CA";
}
my @initdb_params = @custom_opts;
@@ -139,10 +148,10 @@ $oldnode->start;
my $result;
$result = $oldnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -422,10 +431,10 @@ if (-d $log_path)
# Test that upgraded cluster has original locale settings.
$result = $newnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $iculocale_field
+ "SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_iculocale",
+ "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index c05befbb6f..68b2ea8872 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -937,14 +937,18 @@ listAllDbs(const char *pattern, bool verbose)
" d.datctype as \"%s\",\n",
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " d.datlocale as \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" d.daticulocale as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" NULL as \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
" d.daticurules as \"%s\",\n",
@@ -4983,14 +4987,18 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Collate"),
gettext_noop("Ctype"));
- if (pset.sversion >= 150000)
+ if (pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ " c.colllocale AS \"%s\",\n",
+ gettext_noop("Locale"));
+ else if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
" c.colliculocale AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
else
appendPQExpBuffer(&buf,
" c.collcollate AS \"%s\",\n",
- gettext_noop("ICU Locale"));
+ gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf,
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 10c363d2ee..7396ff10c4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -29,6 +29,6 @@
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
- colliculocale => 'und' },
+ colllocale => 'und' },
]
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 5f08eb0a4a..a3e196fb53 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -42,7 +42,7 @@ CATALOG(pg_collation,3456,CollationRelationId)
#ifdef CATALOG_VARLEN /* variable-length fields start here */
text collcollate BKI_DEFAULT(_null_); /* LC_COLLATE setting */
text collctype BKI_DEFAULT(_null_); /* LC_CTYPE setting */
- text colliculocale BKI_DEFAULT(_null_); /* ICU locale ID */
+ text colllocale BKI_DEFAULT(_null_); /* locale ID */
text collicurules BKI_DEFAULT(_null_); /* ICU collation rules */
text collversion BKI_DEFAULT(_null_); /* provider-dependent
* version of collation
@@ -94,7 +94,7 @@ extern Oid CollationCreate(const char *collname, Oid collnamespace,
bool collisdeterministic,
int32 collencoding,
const char *collcollate, const char *collctype,
- const char *colliculocale,
+ const char *colllocale,
const char *collicurules,
const char *collversion,
bool if_not_exists,
diff --git a/src/include/catalog/pg_database.dat b/src/include/catalog/pg_database.dat
index 4306e8a3e8..c2ba636f8d 100644
--- a/src/include/catalog/pg_database.dat
+++ b/src/include/catalog/pg_database.dat
@@ -18,7 +18,7 @@
datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
datallowconn => 't', dathasloginevt => 'f', datconnlimit => '-1', datfrozenxid => '0',
datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
- datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE',
+ datctype => 'LC_CTYPE', datlocale => 'DATLOCALE',
daticurules => 'ICU_RULES', datacl => '_null_' },
]
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 014baa7bab..dbd4379ffa 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -75,7 +75,7 @@ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID
text datctype BKI_FORCE_NOT_NULL;
/* ICU locale ID */
- text daticulocale;
+ text datlocale;
/* ICU collation rules */
text daticurules;
diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out
index 7a05c75967..8ca93f4dea 100644
--- a/src/test/regress/expected/collate.icu.utf8.out
+++ b/src/test/regress/expected/collate.icu.utf8.out
@@ -1024,7 +1024,7 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
@@ -1032,7 +1032,7 @@ ERROR: collation "test0" already exists
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
RESET icu_validation_level;
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index ad02772562..69060fe3c0 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -6221,9 +6221,9 @@ List of schemas
(0 rows)
\dO "no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.access.privilege"
@@ -6410,9 +6410,9 @@ cross-database references are not implemented: "no.such.schema"."no.such.languag
(0 rows)
\dO "no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp "no.such.schema"."no.such.access.privilege"
@@ -6553,9 +6553,9 @@ List of text search templates
(0 rows)
\dO regression."no.such.schema"."no.such.collation"
- List of collations
- Schema | Name | Provider | Collate | Ctype | ICU Locale | ICU Rules | Deterministic?
---------+------+----------+---------+-------+------------+-----------+----------------
+ List of collations
+ Schema | Name | Provider | Collate | Ctype | Locale | ICU Rules | Deterministic?
+--------+------+----------+---------+-------+--------+-----------+----------------
(0 rows)
\dp regression."no.such.schema"."no.such.access.privilege"
diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql
index 3db9e25913..03837de846 100644
--- a/src/test/regress/sql/collate.icu.utf8.sql
+++ b/src/test/regress/sql/collate.icu.utf8.sql
@@ -363,14 +363,14 @@ SET icu_validation_level = disabled;
do $$
BEGIN
EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' ||
- quote_literal((SELECT CASE WHEN datlocprovider='i' THEN daticulocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
+ quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');';
END
$$;
--
2.34.1
[text/x-patch] v22-0002-Introduce-collation-provider-builtin.patch (59.7K, ../../[email protected]/3-v22-0002-Introduce-collation-provider-builtin.patch)
download | inline diff:
From 86eced7fa515f887d4ee68bd84825016237a6f59 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 1 May 2023 15:38:29 -0700
Subject: [PATCH v22 2/7] Introduce collation provider "builtin".
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Initially, the only locale supported by the builtin provider is "C",
which has identical implementation and semantics as the libc
provider's "C" locale.
The builtin provider has one additional capability that libc does not
offer: its locale is entirely independent of the server environment
variables LC_COLLATE and LC_CTYPE. That means that the collation
locale can be "C" while LC_COLLATE and LC_CTYPE are set to "en_US".
By offering a new builtin provider, it clarifies that the semantics
will never depend on libc, and makes it easier to document the
behavior.
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/ff4c2f2f9c8fc7ca27c1c24ae37ecaeaeaff6b53.camel%40j-davis.com
Reviewed-by: Daniel Vérité, Peter Eisentraut, Jeremy Schneider
---
doc/src/sgml/charset.sgml | 80 ++++++++++++----
doc/src/sgml/ref/create_collation.sgml | 11 ++-
doc/src/sgml/ref/create_database.sgml | 7 +-
doc/src/sgml/ref/createdb.sgml | 2 +-
doc/src/sgml/ref/initdb.sgml | 17 +++-
src/backend/catalog/pg_collation.c | 5 +-
src/backend/commands/collationcmds.c | 93 +++++++++++++++----
src/backend/commands/dbcommands.c | 121 +++++++++++++++++++-----
src/backend/utils/adt/formatting.c | 6 ++
src/backend/utils/adt/pg_locale.c | 122 +++++++++++++++++++++----
src/backend/utils/init/postinit.c | 21 ++++-
src/bin/initdb/initdb.c | 58 +++++++-----
src/bin/initdb/t/001_initdb.pl | 40 +++++++-
src/bin/pg_dump/pg_dump.c | 49 ++++++----
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 70 ++++++++++----
src/bin/psql/describe.c | 4 +-
src/bin/scripts/createdb.c | 18 +++-
src/bin/scripts/t/020_createdb.pl | 60 ++++++++++++
src/include/catalog/pg_collation.dat | 6 +-
src/include/catalog/pg_collation.h | 3 +
src/include/utils/pg_locale.h | 6 +-
src/test/icu/t/010_database.pl | 22 ++---
src/test/regress/expected/collate.out | 24 ++++-
src/test/regress/sql/collate.sql | 10 ++
24 files changed, 695 insertions(+), 160 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 4fc143025e..ec7ca390c1 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -342,22 +342,14 @@ initdb --locale=sv_SE
<title>Locale Providers</title>
<para>
- <productname>PostgreSQL</productname> supports multiple <firstterm>locale
- providers</firstterm>. This specifies which library supplies the locale
- data. One standard provider name is <literal>libc</literal>, which uses
- the locales provided by the operating system C library. These are the
- locales used by most tools provided by the operating system. Another
- provider is <literal>icu</literal>, which uses the external
- ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can
- only be used if support for ICU was configured when PostgreSQL was built.
+ A locale provider specifies which library defines the locale behavior for
+ collations and character classifications.
</para>
<para>
The commands and tools that select the locale settings, as described
- above, each have an option to select the locale provider. The examples
- shown earlier all use the <literal>libc</literal> provider, which is the
- default. Here is an example to initialize a database cluster using the
- ICU provider:
+ above, each have an option to select the locale provider. Here is an
+ example to initialize a database cluster using the ICU provider:
<programlisting>
initdb --locale-provider=icu --icu-locale=en
</programlisting>
@@ -370,12 +362,66 @@ initdb --locale-provider=icu --icu-locale=en
</para>
<para>
- Which locale provider to use depends on individual requirements. For most
- basic uses, either provider will give adequate results. For the libc
- provider, it depends on what the operating system offers; some operating
- systems are better than others. For advanced uses, ICU offers more locale
- variants and customization options.
+ Regardless of the locale provider, the operating system is still used to
+ provide some locale-aware behavior, such as messages (see <xref
+ linkend="guc-lc-messages"/>).
</para>
+
+ <para>
+ The available locale providers are listed below.
+ </para>
+
+ <sect3 id="locale-provider-builtin">
+ <title>Builtin</title>
+ <para>
+ The <literal>builtin</literal> provider uses built-in operations. Only
+ the <literal>C</literal> locale is supported for this provider.
+ </para>
+ <para>
+ The <literal>C</literal> locale behavior is identical to the
+ <literal>C</literal> locale in the libc provider. When using this locale,
+ the behavior may depend on the database encoding.
+ </para>
+ </sect3>
+ <sect3 id="locale-provider-icu">
+ <title>ICU</title>
+ <para>
+ The <literal>icu</literal> provider uses the external
+ ICU<indexterm><primary>ICU</primary></indexterm>
+ library. <productname>PostgreSQL</productname> must have been configured
+ with support.
+ </para>
+ <para>
+ ICU provides collation and character classification behavior that is
+ independent of the operating system and database encoding, which is
+ preferable if you expect to transition to other platforms without any
+ change in results. <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal> can be set independently of the ICU locale.
+ </para>
+ <note>
+ <para>
+ For the ICU provider, results may depend on the version of the ICU
+ library used, as it is updated to reflect changes in natural language
+ over time.
+ </para>
+ </note>
+ </sect3>
+ <sect3 id="locale-provider-libc">
+ <title>libc</title>
+ <para>
+ The <literal>libc</literal> provider uses the operating system's C
+ library. The collation and character classification behavior is
+ controlled by the settings <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal>, so they cannot be set independently.
+ </para>
+ <note>
+ <para>
+ The same locale name may have different behavior on different platforms
+ when using the libc provider.
+ </para>
+ </note>
+ </sect3>
+
</sect2>
<sect2 id="icu-locales">
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 5cf9777764..98cd7d56be 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -96,6 +96,11 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<replaceable>locale</replaceable>, you cannot specify either of those
parameters.
</para>
+ <para>
+ If <replaceable>provider</replaceable> is <literal>builtin</literal>,
+ then <replaceable>locale</replaceable> must be specified and set to
+ <literal>C</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -129,9 +134,9 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<listitem>
<para>
Specifies the provider to use for locale services associated with this
- collation. Possible values are
- <literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
- (if the server was built with ICU support) or <literal>libc</literal>.
+ collation. Possible values are <literal>builtin</literal>,
+ <literal>icu</literal><indexterm><primary>ICU</primary></indexterm> (if
+ the server was built with ICU support) or <literal>libc</literal>.
<literal>libc</literal> is the default. See <xref
linkend="locale-providers"/> for details.
</para>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 72927960eb..6c1fd95602 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -162,6 +162,11 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
linkend="create-database-lc-ctype"/>, or <xref
linkend="create-database-icu-locale"/> individually.
</para>
+ <para>
+ If <xref linkend="create-database-locale-provider"/> is
+ <literal>builtin</literal>, then <replaceable>locale</replaceable>
+ must be specified and set to <literal>C</literal>.
+ </para>
<tip>
<para>
The other locale settings <xref linkend="guc-lc-messages"/>, <xref
@@ -243,7 +248,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<listitem>
<para>
Specifies the provider to use for the default collation in this
- database. Possible values are
+ database. Possible values are <literal>builtin</literal>,
<literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
(if the server was built with ICU support) or <literal>libc</literal>.
By default, the provider is the same as that of the <xref
diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml
index e4647d5ce7..d3e815f659 100644
--- a/doc/src/sgml/ref/createdb.sgml
+++ b/doc/src/sgml/ref/createdb.sgml
@@ -171,7 +171,7 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
Specifies the locale provider for the database's default collation.
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index cd75cae10e..4760570f6a 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -286,6 +286,11 @@ PostgreSQL documentation
environment that <command>initdb</command> runs in. Locale
support is described in <xref linkend="locale"/>.
</para>
+ <para>
+ If <option>--locale-provider</option> is <literal>builtin</literal>,
+ <option>--locale</option> must be specified and set to
+ <literal>C</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -314,8 +319,18 @@ PostgreSQL documentation
</listitem>
</varlistentry>
+ <varlistentry id="app-initdb-builtin-locale">
+ <term><option>--builtin-locale=<replaceable>locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the locale name when the builtin provider is used. Locale support
+ is described in <xref linkend="locale"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-initdb-option-locale-provider">
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
This option sets the locale provider for databases created in the new
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index e42f2afccb..7f2f701229 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -64,7 +64,10 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colllocale);
+ Assert((collprovider == COLLPROVIDER_LIBC &&
+ collcollate && collctype && !colllocale) ||
+ (collprovider != COLLPROVIDER_LIBC &&
+ !collcollate && !collctype && colllocale));
/*
* Make sure there is no existing collation of same name & encoding.
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 59d7e17804..8e6cb11f81 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -66,7 +66,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colllocale;
+ const char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -213,7 +213,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (collproviderstr)
{
- if (pg_strcasecmp(collproviderstr, "icu") == 0)
+ if (pg_strcasecmp(collproviderstr, "builtin") == 0)
+ collprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(collproviderstr, "icu") == 0)
collprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(collproviderstr, "libc") == 0)
collprovider = COLLPROVIDER_LIBC;
@@ -243,7 +245,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (lcctypeEl)
collctype = defGetString(lcctypeEl);
- if (collprovider == COLLPROVIDER_LIBC)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ if (!colllocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("parameter \"locale\" must be specified")));
+
+ colllocale = builtin_validate_locale(GetDatabaseEncoding(),
+ colllocale);
+ }
+ else if (collprovider == COLLPROVIDER_LIBC)
{
if (!collcollate)
ereport(ERROR,
@@ -303,7 +315,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
- if (collprovider == COLLPROVIDER_ICU)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * Behavior may be different in different encodings, so set
+ * collencoding to the current database encoding. No validation is
+ * required, because the "builtin" provider is compatible with any
+ * encoding.
+ */
+ collencoding = GetDatabaseEncoding();
+ }
+ else if (collprovider == COLLPROVIDER_ICU)
{
#ifdef USE_ICU
/*
@@ -332,7 +354,18 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
+ {
+ const char *locale;
+
+ if (collprovider == COLLPROVIDER_ICU)
+ locale = colllocale;
+ else if (collprovider == COLLPROVIDER_LIBC)
+ locale = collcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ collversion = get_collation_actual_version(collprovider, locale);
+ }
newoid = CollationCreate(collName,
collNamespace,
@@ -407,6 +440,7 @@ AlterCollation(AlterCollationStmt *stmt)
Form_pg_collation collForm;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
ObjectAddress address;
@@ -433,8 +467,20 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
+ if (collForm->collprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (collForm->collprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(collForm->collprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -498,11 +544,18 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_datlocale : Anum_pg_database_datcollate);
-
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(dbtup);
}
@@ -519,11 +572,19 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttrNotNull(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(colltp);
}
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 0f27d7b14c..096402400a 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -697,6 +697,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
DefElem *dtemplate = NULL;
DefElem *dencoding = NULL;
DefElem *dlocale = NULL;
+ DefElem *dbuiltinlocale = NULL;
DefElem *dcollate = NULL;
DefElem *dctype = NULL;
DefElem *diculocale = NULL;
@@ -712,7 +713,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dblocale = NULL;
+ const char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -761,6 +762,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errorConflictingDefElem(defel, pstate);
dlocale = defel;
}
+ else if (strcmp(defel->defname, "builtin_locale") == 0)
+ {
+ if (dbuiltinlocale)
+ errorConflictingDefElem(defel, pstate);
+ dbuiltinlocale = defel;
+ }
else if (strcmp(defel->defname, "lc_collate") == 0)
{
if (dcollate)
@@ -896,7 +903,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
dbcollate = defGetString(dlocale);
dbctype = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
}
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ dblocale = defGetString(dbuiltinlocale);
if (dcollate && dcollate->arg)
dbcollate = defGetString(dcollate);
if (dctype && dctype->arg)
@@ -909,7 +919,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *locproviderstr = defGetString(dlocprovider);
- if (pg_strcasecmp(locproviderstr, "icu") == 0)
+ if (pg_strcasecmp(locproviderstr, "builtin") == 0)
+ dblocprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(locproviderstr, "icu") == 0)
dblocprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(locproviderstr, "libc") == 0)
dblocprovider = COLLPROVIDER_LIBC;
@@ -1026,14 +1038,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
- {
- if (dlocale && dlocale->arg)
- dblocale = defGetString(dlocale);
- else
- dblocale = src_locale;
- }
- if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL)
+ dblocale = src_locale;
+ if (dbicurules == NULL)
dbicurules = src_icurules;
/* Some encodings are client only */
@@ -1058,6 +1065,27 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
check_encoding_locale_matches(encoding, dbcollate, dbctype);
+ if (dblocprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * This would happen if template0 uses the libc provider but the new
+ * database uses builtin.
+ */
+ if (!dblocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("LOCALE must be specified for the builtin provider")));
+
+ dblocale = builtin_validate_locale(encoding, dblocale);
+ }
+ else
+ {
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("BUILTIN_LOCALE cannot be specified unless locale provider is builtin")));
+ }
+
if (dblocprovider == COLLPROVIDER_ICU)
{
if (!(is_encoding_supported_by_icu(encoding)))
@@ -1099,7 +1127,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
}
else
{
- if (dblocale)
+ if (diculocale && diculocale->arg)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1110,6 +1138,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
}
+ /* for libc, locale comes from datcollate and datctype */
+ if (dblocprovider == COLLPROVIDER_LIBC)
+ dblocale = NULL;
+
/*
* Check that the new encoding and locale settings match the source
* database. We insist on this because we simply copy the source data ---
@@ -1195,8 +1227,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (src_collversion && !dcollversion)
{
char *actual_versionstr;
+ const char *locale;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ actual_versionstr = get_collation_actual_version(dblocprovider, locale);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1224,7 +1264,18 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ {
+ const char *locale;
+
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ dbcollversion = get_collation_actual_version(dblocprovider, locale);
+ }
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1363,8 +1414,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dblocale));
+ Assert((dblocprovider != COLLPROVIDER_LIBC && dblocale) ||
+ (dblocprovider == COLLPROVIDER_LIBC && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -2445,6 +2496,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
ObjectAddress address;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
@@ -2471,10 +2523,24 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
- newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
+ if (datForm->datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datlocale, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datForm->datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(datForm->datlocprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -2659,6 +2725,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
+ char *locale;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2669,8 +2736,20 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
- version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
+ if (datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ version = get_collation_actual_version(datlocprovider, locale);
ReleaseSysCache(tp);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 036a463491..5f483b8dbc 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1680,6 +1680,8 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
else
#endif
{
+ Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
+
if (pg_database_encoding_max_length() > 1)
{
wchar_t *workspace;
@@ -1798,6 +1800,8 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
else
#endif
{
+ Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
+
if (pg_database_encoding_max_length() > 1)
{
wchar_t *workspace;
@@ -1917,6 +1921,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
else
#endif
{
+ Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
+
if (pg_database_encoding_max_length() > 1)
{
wchar_t *workspace;
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 77d5752dc8..1b3fb3822b 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1268,7 +1268,19 @@ lookup_collation_cache(Oid collation, bool set_flags)
elog(ERROR, "cache lookup failed for collation %u", collation);
collform = (Form_pg_collation) GETSTRUCT(tp);
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ Datum datum;
+ const char *colllocale;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ colllocale = TextDatumGetCString(datum);
+
+ cache_entry->collate_is_c = true;
+ cache_entry->ctype_is_c = ((strcmp(colllocale, "C") == 0) ||
+ (strcmp(colllocale, "POSIX") == 0));
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
const char *collcollate;
@@ -1319,16 +1331,30 @@ lc_collate_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_COLLATE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_COLLATE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ result = true;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1372,16 +1398,29 @@ lc_ctype_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_CTYPE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_CTYPE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ localeptr = default_locale.info.builtin.locale;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1519,10 +1558,10 @@ pg_newlocale_from_collation(Oid collid)
if (collid == DEFAULT_COLLATION_OID)
{
- if (default_locale.provider == COLLPROVIDER_ICU)
- return &default_locale;
- else
+ if (default_locale.provider == COLLPROVIDER_LIBC)
return (pg_locale_t) 0;
+ else
+ return &default_locale;
}
cache_entry = lookup_collation_cache(collid, false);
@@ -1547,7 +1586,20 @@ pg_newlocale_from_collation(Oid collid)
result.provider = collform->collprovider;
result.deterministic = collform->collisdeterministic;
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ const char *locstr;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ locstr = TextDatumGetCString(datum);
+
+ if (strcmp(locstr, "C") != 0)
+ elog(ERROR, "unexpected builtin locale: %s", locstr);
+
+ result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
+ locstr);
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
const char *collcollate;
const char *collctype pg_attribute_unused();
@@ -1626,6 +1678,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
+ Assert(collform->collprovider != COLLPROVIDER_BUILTIN);
datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
@@ -1677,6 +1730,10 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
+ /* the builtin collation provider is not versioned */
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ return NULL;
+
#ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU)
{
@@ -2443,6 +2500,33 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
return result;
}
+const char *
+builtin_validate_locale(int encoding, const char *locale)
+{
+ const char *canonical_name = NULL;
+ int required_encoding = -1;
+
+ if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0)
+ {
+ canonical_name = "C";
+ }
+
+ if (!canonical_name)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ locale)));
+
+ if (required_encoding >= 0 && encoding != required_encoding)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("encoding \"%s\" does not match locale \"%s\"",
+ pg_encoding_to_char(encoding), locale)));
+
+ return canonical_name;
+}
+
+
#ifdef USE_ICU
/*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 2875bc97d3..5bb0bd65e6 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -423,7 +423,18 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
strcmp(ctype, "POSIX") == 0)
database_ctype_is_c = true;
- if (dbform->datlocprovider == COLLPROVIDER_ICU)
+ if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
+
+ if (strcmp(datlocale, "C") != 0)
+ elog(ERROR, "unexpected builtin locale: %s", datlocale);
+
+ default_locale.info.builtin.locale = MemoryContextStrdup(
+ TopMemoryContext, datlocale);
+ }
+ else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
char *icurules;
@@ -461,10 +472,16 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *actual_versionstr;
char *collversionstr;
+ char *locale;
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
+ if (dbform->datlocprovider == COLLPROVIDER_LIBC)
+ locale = collate;
+ else
+ locale = datlocale;
+
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 4d78155759..f35ead7346 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -146,6 +146,7 @@ static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
static char *datlocale = NULL;
+static bool icu_locale_specified = false;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -2395,14 +2396,13 @@ setlocales(void)
lc_messages = canonname;
#endif
+ if (locale_provider != COLLPROVIDER_LIBC && datlocale == NULL)
+ pg_fatal("locale must be specified unless provider is libc");
+
if (locale_provider == COLLPROVIDER_ICU)
{
char *langtag;
- /* acquire default locale from the environment, if not specified */
- if (datlocale == NULL)
- pg_fatal("ICU locale must be specified");
-
/* canonicalize to a language tag */
langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
@@ -2447,7 +2447,8 @@ usage(const char *progname)
" set default locale in the respective category for\n"
" new databases (default taken from environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --builtin-locale=LOCALE set builtin locale name for new databases\n"));
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" set default locale provider for new databases\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
printf(_(" -T, --text-search-config=CFG\n"
@@ -2598,20 +2599,28 @@ setup_locale_encoding(void)
{
setlocales();
- if (locale_provider == COLLPROVIDER_LIBC &&
- strcmp(lc_ctype, lc_collate) == 0 &&
- strcmp(lc_ctype, lc_time) == 0 &&
- strcmp(lc_ctype, lc_numeric) == 0 &&
- strcmp(lc_ctype, lc_monetary) == 0 &&
- strcmp(lc_ctype, lc_messages) == 0 &&
- (!datlocale || strcmp(lc_ctype, datlocale) == 0))
+ if (locale_provider == COLLPROVIDER_BUILTIN &&
+ strcmp(lc_ctype, "C") == 0 &&
+ strcmp(lc_collate, "C") == 0 &&
+ strcmp(lc_time, "C") == 0 &&
+ strcmp(lc_numeric, "C") == 0 &&
+ strcmp(lc_monetary, "C") == 0 &&
+ strcmp(lc_messages, "C") == 0)
+ printf(_("The database cluster will be initialized with no locale.\n"));
+ else if (locale_provider == COLLPROVIDER_LIBC &&
+ strcmp(lc_ctype, lc_collate) == 0 &&
+ strcmp(lc_ctype, lc_time) == 0 &&
+ strcmp(lc_ctype, lc_numeric) == 0 &&
+ strcmp(lc_ctype, lc_monetary) == 0 &&
+ strcmp(lc_ctype, lc_messages) == 0 &&
+ (!datlocale || strcmp(lc_ctype, datlocale) == 0))
printf(_("The database cluster will be initialized with locale \"%s\".\n"), lc_ctype);
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
- printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (datlocale)
- printf(_(" ICU locale: %s\n"), datlocale);
+ printf(_(" default collation provider: %s\n"), collprovider_name(locale_provider));
+ if (locale_provider != COLLPROVIDER_LIBC)
+ printf(_(" default collation locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3104,9 +3113,10 @@ main(int argc, char *argv[])
{"allow-group-access", no_argument, NULL, 'g'},
{"discard-caches", no_argument, NULL, 14},
{"locale-provider", required_argument, NULL, 15},
- {"icu-locale", required_argument, NULL, 16},
- {"icu-rules", required_argument, NULL, 17},
- {"sync-method", required_argument, NULL, 18},
+ {"builtin-locale", required_argument, NULL, 16},
+ {"icu-locale", required_argument, NULL, 17},
+ {"icu-rules", required_argument, NULL, 18},
+ {"sync-method", required_argument, NULL, 19},
{NULL, 0, NULL, 0}
};
@@ -3274,7 +3284,9 @@ main(int argc, char *argv[])
"-c debug_discard_caches=1");
break;
case 15:
- if (strcmp(optarg, "icu") == 0)
+ if (strcmp(optarg, "builtin") == 0)
+ locale_provider = COLLPROVIDER_BUILTIN;
+ else if (strcmp(optarg, "icu") == 0)
locale_provider = COLLPROVIDER_ICU;
else if (strcmp(optarg, "libc") == 0)
locale_provider = COLLPROVIDER_LIBC;
@@ -3285,9 +3297,13 @@ main(int argc, char *argv[])
datlocale = pg_strdup(optarg);
break;
case 17:
- icu_rules = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
+ icu_locale_specified = true;
break;
case 18:
+ icu_rules = pg_strdup(optarg);
+ break;
+ case 19:
if (!parse_sync_method(optarg, &sync_method))
exit(1);
break;
@@ -3317,7 +3333,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (datlocale && locale_provider != COLLPROVIDER_ICU)
+ if (icu_locale_specified && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 594b20cc74..45aef30282 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -117,7 +117,7 @@ if ($ENV{with_icu} eq 'yes')
{
command_fails_like(
[ 'initdb', '--no-sync', '--locale-provider=icu', "$tempdir/data2" ],
- qr/initdb: error: ICU locale must be specified/,
+ qr/initdb: error: locale must be specified unless provider is libc/,
'locale provider ICU requires --icu-locale');
command_ok(
@@ -138,7 +138,7 @@ if ($ENV{with_icu} eq 'yes')
'--lc-monetary=C', '--lc-time=C',
"$tempdir/data4"
],
- qr/^\s+ICU locale:\s+und\n/ms,
+ qr/^\s+default collation locale:\s+und\n/ms,
'options --locale-provider=icu --locale=und --lc-*=C');
command_fails_like(
@@ -184,6 +184,42 @@ else
'locale provider ICU fails since no ICU support');
}
+command_fails(
+ [ 'initdb', '--no-sync', '--locale-provider=builtin', "$tempdir/data6" ],
+ 'locale provider builtin fails without --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--locale=C',
+ "$tempdir/data7"
+ ],
+ 'locale provider builtin with --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--lc-ctype=C',
+ '--locale=C', "$tempdir/data10"
+ ],
+ 'locale provider builtin with --lc-ctype');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-locale=en',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU locale');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-rules=""',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU rules');
+
command_fails(
[ 'initdb', '--no-sync', '--locale-provider=xyz', "$tempdir/dataX" ],
'fails for invalid locale provider');
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 23e6217b73..0e4e7565ae 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3114,7 +3114,9 @@ dumpDatabase(Archive *fout)
}
appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
- if (datlocprovider[0] == 'c')
+ if (datlocprovider[0] == 'b')
+ appendPQExpBufferStr(creaQry, "builtin");
+ else if (datlocprovider[0] == 'c')
appendPQExpBufferStr(creaQry, "libc");
else if (datlocprovider[0] == 'i')
appendPQExpBufferStr(creaQry, "icu");
@@ -3122,27 +3124,33 @@ dumpDatabase(Archive *fout)
pg_fatal("unrecognized locale provider: %s",
datlocprovider);
- if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ if (!locale && datlocprovider[0] != 'c')
+ pg_log_warning("database '%s' with provider '%s' missing datlocale",
+ datname, datlocprovider);
+
+ if (locale && datlocprovider[0] == 'c')
+ pg_log_warning("database '%s' with provider 'c' has non-NULL locale '%s'",
+ datname, locale);
+
+ /* if collate and ctype are equal, and locale is NULL, use LOCALE */
+ if (!locale && strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ locale = collate;
+
+ /* output LC_COLLATE and LC_CTYPE if different from LOCALE */
+ if (strlen(collate) > 0 && (!locale || strcmp(collate, locale) != 0))
{
- appendPQExpBufferStr(creaQry, " LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
appendStringLiteralAH(creaQry, collate, fout);
}
- else
+ if (strlen(ctype) > 0 && (!locale || strcmp(ctype, locale) != 0))
{
- if (strlen(collate) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
- appendStringLiteralAH(creaQry, collate, fout);
- }
- if (strlen(ctype) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
- appendStringLiteralAH(creaQry, ctype, fout);
- }
+ appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+ appendStringLiteralAH(creaQry, ctype, fout);
}
+
if (locale)
{
- appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LOCALE = ");
appendStringLiteralAH(creaQry, locale, fout);
}
@@ -13870,7 +13878,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
fmtQualifiedDumpable(collinfo));
appendPQExpBufferStr(q, "provider = ");
- if (collprovider[0] == 'c')
+ if (collprovider[0] == 'b')
+ appendPQExpBufferStr(q, "builtin");
+ else if (collprovider[0] == 'c')
appendPQExpBufferStr(q, "libc");
else if (collprovider[0] == 'i')
appendPQExpBufferStr(q, "icu");
@@ -13891,6 +13901,13 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
/* no locale -- the default collation cannot be reloaded anyway */
}
+ else if (collprovider[0] == 'b')
+ {
+ if (collcollate || collctype || colllocale || collicurules)
+ pg_log_warning("invalid collation \"%s\"", qcollname);
+
+ appendPQExpBufferStr(q, ", locale = 'C'");
+ }
else if (collprovider[0] == 'i')
{
if (fout->remoteVersion >= 150000)
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index 41d06d272b..e8cb7cc60e 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -110,13 +110,16 @@ my $oldversion = int($oldnode->pg_version =~ s/([0-9]*).*/$1/rg);
# can test that pg_upgrade copies the locale settings of template0
# from the old to the new cluster.
-my $original_encoding = "6"; # UTF-8
-my $original_provider = "c";
-my $original_locale = "C";
-my $original_datlocale = "";
-my $provider_field = "'c' AS datlocprovider";
-my $datlocale_field = "NULL AS datlocale";
-if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+my %encoding_number = ('UTF-8' => 6, 'SQL_ASCII' => 0);
+my $provider_field;
+my $datlocale_field;
+my $original_encoding;
+my $original_provider;
+my $original_datcollate = "C";
+my $original_datctype = "C";
+my $original_datlocale;
+
+if ($oldversion >= 15)
{
$provider_field = "datlocprovider";
if ($oldversion >= 17)
@@ -127,18 +130,52 @@ if ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
$datlocale_field = "daticulocale AS datlocale";
}
+}
+else
+{
+ $provider_field = "'c' AS datlocprovider";
+ $datlocale_field = "NULL AS datlocale";
+}
+
+if ($oldversion >= 17)
+{
+ $original_encoding = "UTF-8";
+ $original_provider = "b";
+ $original_datlocale = "C";
+}
+elsif ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
+{
+ $original_encoding = "UTF-8";
$original_provider = "i";
$original_datlocale = "fr-CA";
}
+else
+{
+ my $original_encoding = "SQL_ASCII";
+ my $original_provider = "c";
+ my $original_datlocale = "";
+}
my @initdb_params = @custom_opts;
-push @initdb_params, ('--encoding', 'UTF-8');
-push @initdb_params, ('--locale', $original_locale);
-if ($original_provider eq "i")
+push @initdb_params, ('--encoding', $original_encoding);
+push @initdb_params, ('--lc-collate', $original_datcollate);
+push @initdb_params, ('--lc-ctype', $original_datctype);
+
+# add --locale-provider, if supported
+my %provider_name = ('b' => 'builtin', 'i' => 'icu', 'c' => 'libc');
+if ($oldnode->pg_version >= 15)
{
- push @initdb_params, ('--locale-provider', 'icu');
- push @initdb_params, ('--icu-locale', 'fr-CA');
+ push @initdb_params,
+ ('--locale-provider', $provider_name{$original_provider});
+ if ($original_provider eq 'b')
+ {
+ push @initdb_params, ('--builtin-locale', $original_datlocale);
+ }
+ elsif ($original_provider eq 'i')
+ {
+ push @initdb_params, ('--icu-locale', $original_datlocale);
+ }
}
$node_params{extra} = \@initdb_params;
@@ -151,7 +188,7 @@ $result = $oldnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -327,7 +364,8 @@ if (defined($ENV{oldinstall}))
}
# Create an invalid database, will be deleted below
-$oldnode->safe_psql('postgres', qq(
+$oldnode->safe_psql(
+ 'postgres', qq(
CREATE DATABASE regression_invalid;
UPDATE pg_database SET datconnlimit = -2 WHERE datname = 'regression_invalid';
));
@@ -370,7 +408,7 @@ command_checks_all(
$mode, '--check',
],
1,
- [qr/invalid/], # pg_upgrade prints errors on stdout :(
+ [qr/invalid/], # pg_upgrade prints errors on stdout :(
[qr//],
'invalid database causes failure');
rmtree($newnode->data_dir . "/pg_upgrade_output.d");
@@ -434,7 +472,7 @@ $result = $newnode->safe_psql(
"SELECT encoding, $provider_field, datcollate, datctype, $datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$encoding_number{$original_encoding}|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 68b2ea8872..1ab80eb7ca 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -926,7 +926,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Encoding"));
if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
- " CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE d.datlocprovider WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Locale Provider"));
else
appendPQExpBuffer(&buf,
@@ -4974,7 +4974,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
if (pset.sversion >= 100000)
appendPQExpBuffer(&buf,
- " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Provider"));
else
appendPQExpBuffer(&buf,
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
index 14970a6a5f..4af4b98181 100644
--- a/src/bin/scripts/createdb.c
+++ b/src/bin/scripts/createdb.c
@@ -40,8 +40,9 @@ main(int argc, char *argv[])
{"locale", required_argument, NULL, 'l'},
{"maintenance-db", required_argument, NULL, 3},
{"locale-provider", required_argument, NULL, 4},
- {"icu-locale", required_argument, NULL, 5},
- {"icu-rules", required_argument, NULL, 6},
+ {"builtin-locale", required_argument, NULL, 5},
+ {"icu-locale", required_argument, NULL, 6},
+ {"icu-rules", required_argument, NULL, 7},
{NULL, 0, NULL, 0}
};
@@ -67,6 +68,7 @@ main(int argc, char *argv[])
char *lc_ctype = NULL;
char *locale = NULL;
char *locale_provider = NULL;
+ char *builtin_locale = NULL;
char *icu_locale = NULL;
char *icu_rules = NULL;
@@ -134,9 +136,12 @@ main(int argc, char *argv[])
locale_provider = pg_strdup(optarg);
break;
case 5:
- icu_locale = pg_strdup(optarg);
+ builtin_locale = pg_strdup(optarg);
break;
case 6:
+ icu_locale = pg_strdup(optarg);
+ break;
+ case 7:
icu_rules = pg_strdup(optarg);
break;
default:
@@ -216,6 +221,11 @@ main(int argc, char *argv[])
appendPQExpBufferStr(&sql, " LOCALE ");
appendStringLiteralConn(&sql, locale, conn);
}
+ if (builtin_locale)
+ {
+ appendPQExpBufferStr(&sql, " BUILTIN_LOCALE ");
+ appendStringLiteralConn(&sql, builtin_locale, conn);
+ }
if (lc_collate)
{
appendPQExpBufferStr(&sql, " LC_COLLATE ");
@@ -296,7 +306,7 @@ help(const char *progname)
printf(_(" --lc-ctype=LOCALE LC_CTYPE setting for the database\n"));
printf(_(" --icu-locale=LOCALE ICU locale setting for the database\n"));
printf(_(" --icu-rules=RULES ICU rules setting for the database\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" locale provider for the database's default collation\n"));
printf(_(" -O, --owner=OWNER database user to own the new database\n"));
printf(_(" -S, --strategy=STRATEGY database creation strategy wal_log or file_copy\n"));
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index 37e47b0078..dfd635bfab 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -105,6 +105,66 @@ else
'create database with ICU fails since no ICU support');
}
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ 'tbuiltin1'
+ ],
+ 'create database with provider "builtin" fails without --locale');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin2'
+ ],
+ 'create database with provider "builtin" and locale "C"');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-collate=C',
+ 'tbuiltin3'
+ ],
+ 'create database with provider "builtin" and LC_COLLATE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-ctype=C',
+ 'tbuiltin4'
+ ],
+ 'create database with provider "builtin" and LC_CTYPE=C');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-locale=en',
+ 'tbuiltin7'
+ ],
+ 'create database with provider "builtin" and ICU_LOCALE="en"');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-rules=""',
+ 'tbuiltin8'
+ ],
+ 'create database with provider "builtin" and ICU_RULES=""');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template1', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin9'
+ ],
+ 'create database with provider "builtin" not matching template');
+
$node->command_fails([ 'createdb', 'foobar1' ],
'fails if database already exists');
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 7396ff10c4..938432e8a4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -23,9 +23,9 @@
descr => 'standard POSIX collation',
collname => 'POSIX', collprovider => 'c', collencoding => '-1',
collcollate => 'POSIX', collctype => 'POSIX' },
-{ oid => '962', descr => 'sorts by Unicode code point',
- collname => 'ucs_basic', collprovider => 'c', collencoding => '6',
- collcollate => 'C', collctype => 'C' },
+{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',
+ collname => 'ucs_basic', collprovider => 'b', collencoding => '6',
+ colllocale => 'C' },
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index a3e196fb53..5ce289d74b 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -68,6 +68,7 @@ MAKE_SYSCACHE(COLLOID, pg_collation_oid_index, 8);
#ifdef EXPOSE_TO_CLIENT_CODE
#define COLLPROVIDER_DEFAULT 'd'
+#define COLLPROVIDER_BUILTIN 'b'
#define COLLPROVIDER_ICU 'i'
#define COLLPROVIDER_LIBC 'c'
@@ -76,6 +77,8 @@ collprovider_name(char c)
{
switch (c)
{
+ case COLLPROVIDER_BUILTIN:
+ return "builtin";
case COLLPROVIDER_ICU:
return "icu";
case COLLPROVIDER_LIBC:
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 28c925b5af..2fd0c5157b 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -76,6 +76,10 @@ struct pg_locale_struct
bool deterministic;
union
{
+ struct
+ {
+ const char *locale;
+ } builtin;
locale_t lt;
#ifdef USE_ICU
struct
@@ -112,7 +116,7 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
pg_locale_t locale);
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
size_t srclen, pg_locale_t locale);
-
+extern const char *builtin_validate_locale(int encoding, const char *loc_str);
extern void icu_validate_locale(const char *loc_str);
extern char *icu_language_tag(const char *loc_str, int elevel);
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
index 8a1fc12ec6..5f8ef16803 100644
--- a/src/test/icu/t/010_database.pl
+++ b/src/test/icu/t/010_database.pl
@@ -27,9 +27,8 @@ CREATE TABLE icu (def text, en text COLLATE "en-x-icu", upfirst text COLLATE upp
INSERT INTO icu VALUES ('a', 'a', 'a'), ('b', 'b', 'b'), ('A', 'A', 'A'), ('B', 'B', 'B');
});
-is( $node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
- qq(t),
- 'ICU unicode version defined');
+is($node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
+ qq(t), 'ICU unicode version defined');
is( $node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY def}),
qq(A
@@ -63,14 +62,13 @@ is( $node1->psql(
0,
"C locale works for ICU");
-# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
-# are specified
-is( $node1->psql(
- 'postgres',
- q{CREATE DATABASE dbicu2 LOCALE_PROVIDER icu LOCALE '@colStrength=primary'
- LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0 ENCODING UTF8}
- ),
- 0,
- "LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE are specified");
+my ($ret, $stdout, $stderr) = $node1->psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
+);
+isnt($ret, 0, "locale provider must match template: exit code not 0");
+like(
+ $stderr,
+ qr/ERROR: new locale provider \(builtin\) does not match locale provider of the template database \(icu\)/,
+ "locale provider must match template: error message");
done_testing();
diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out
index 0649564485..ece4a8e99d 100644
--- a/src/test/regress/expected/collate.out
+++ b/src/test/regress/expected/collate.out
@@ -650,6 +650,26 @@ EXPLAIN (COSTS OFF)
(3 rows)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+ b
+-----
+ ABD
+ Abc
+ abc
+ bbc
+(4 rows)
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+ERROR: invalid locale name "en_US" for builtin provider
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+ERROR: conflicting or redundant options
+DETAIL: LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
@@ -754,7 +774,7 @@ DETAIL: FROM cannot be specified together with any other options.
-- must get rid of them.
--
DROP SCHEMA collate_tests CASCADE;
-NOTICE: drop cascades to 19 other objects
+NOTICE: drop cascades to 21 other objects
DETAIL: drop cascades to table collate_test1
drop cascades to table collate_test_like
drop cascades to table collate_test2
@@ -771,6 +791,8 @@ drop cascades to function dup(anyelement)
drop cascades to table collate_test20
drop cascades to table collate_test21
drop cascades to table collate_test22
+drop cascades to collation builtin_c
+drop cascades to collation builtin_posix
drop cascades to collation mycoll2
drop cascades to table collate_test23
drop cascades to view collate_on_int
diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql
index c3d40fc195..01d5c69fe4 100644
--- a/src/test/regress/sql/collate.sql
+++ b/src/test/regress/sql/collate.sql
@@ -244,6 +244,16 @@ EXPLAIN (COSTS OFF)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+CREATE COLLATION builtin_posix ( PROVIDER = builtin, LOCALE = "POSIX" );
+
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "POSIX", LC_CTYPE = "POSIX" ); -- fails
+
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
--
2.34.1
[text/x-patch] v22-0003-Add-C.UTF-8-locale-to-the-new-builtin-collation-.patch (27.4K, ../../[email protected]/4-v22-0003-Add-C.UTF-8-locale-to-the-new-builtin-collation-.patch)
download | inline diff:
From a7e476e29a9a622f361a9428153c971763eaac6e Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 17:41:51 -0800
Subject: [PATCH v22 3/7] Add C.UTF-8 locale to the new builtin collation
provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The builtin C.UTF-8 locale has similar semantics to the libc locale of
the same name. That is, code point sort order (fast, memcmp-based)
combined with Unicode semantics for character operations such as
pattern matching, regular expressions, and
LOWER()/INITCAP()/UPPER(). The character semantics are based on
Unicode simple case mappings.
The builtin provider's C.UTF-8 offers several important advantages
over libc:
* faster sorting -- benefits from additional optimizations such as
abbreviated keys and varstrfastcmp_c
* faster case conversion, e.g. LOWER(), at least compared with some
libc implementations
* available on all platforms with identical semantics, and the
semantics are stable, testable, and documentable within a given
Postgres major version
Being based on memcmp, the builtin C.UTF-8 locale does not offer
natural language sort order. But it is an improvement for most use
cases that might otherwise use libc's "C.UTF-8" locale, as well as
many use cases that use libc's "C" locale.
Discussion: https://postgr.es/m/ff4c2f2f9c8fc7ca27c1c24ae37ecaeaeaff6b53.camel%40j-davis.com
Reviewed-by: Daniel Vérité, Peter Eisentraut, Jeremy Schneider
---
doc/src/sgml/charset.sgml | 27 +++-
doc/src/sgml/ref/create_collation.sgml | 2 +-
doc/src/sgml/ref/create_database.sgml | 3 +-
doc/src/sgml/ref/initdb.sgml | 2 +-
src/backend/regex/regc_pg_locale.c | 36 +++++-
src/backend/utils/adt/formatting.c | 123 ++++++++++++++++++
src/backend/utils/adt/pg_locale.c | 18 ++-
src/backend/utils/init/postinit.c | 2 +-
src/bin/initdb/t/001_initdb.pl | 17 +++
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 2 +-
src/bin/scripts/t/020_createdb.pl | 18 +++
src/include/catalog/pg_collation.dat | 3 +
src/test/regress/expected/collate.utf8.out | 128 +++++++++++++++++++
src/test/regress/expected/collate.utf8_1.out | 8 ++
src/test/regress/parallel_schedule | 4 +-
src/test/regress/sql/collate.utf8.sql | 59 +++++++++
16 files changed, 441 insertions(+), 11 deletions(-)
create mode 100644 src/test/regress/expected/collate.utf8.out
create mode 100644 src/test/regress/expected/collate.utf8_1.out
create mode 100644 src/test/regress/sql/collate.utf8.sql
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index ec7ca390c1..08b534db98 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -375,13 +375,21 @@ initdb --locale-provider=icu --icu-locale=en
<title>Builtin</title>
<para>
The <literal>builtin</literal> provider uses built-in operations. Only
- the <literal>C</literal> locale is supported for this provider.
+ the <literal>C</literal> and <literal>C.UTF-8</literal> locales are
+ supported for this provider.
</para>
<para>
The <literal>C</literal> locale behavior is identical to the
<literal>C</literal> locale in the libc provider. When using this locale,
the behavior may depend on the database encoding.
</para>
+ <para>
+ The <literal>C.UTF-8</literal> locale is available only for when the
+ database encoding is <literal>UTF-8</literal>, and the behavior is based
+ on Unicode. The collation uses the code point values only. The regular
+ expression character classes are based on the "POSIX Compatible"
+ semantics, and the case mapping is the "simple" variant.
+ </para>
</sect3>
<sect3 id="locale-provider-icu">
<title>ICU</title>
@@ -868,6 +876,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_c_utf8</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function>, it uses
+ Unicode simple case mapping. For pattern matching (including regular
+ expressions), it uses the POSIX Compatible variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. This collation is
+ only available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
<listitem>
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 98cd7d56be..85f18cbbe5 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -99,7 +99,7 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<para>
If <replaceable>provider</replaceable> is <literal>builtin</literal>,
then <replaceable>locale</replaceable> must be specified and set to
- <literal>C</literal>.
+ either <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 6c1fd95602..1f5cdf1271 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -165,7 +165,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<para>
If <xref linkend="create-database-locale-provider"/> is
<literal>builtin</literal>, then <replaceable>locale</replaceable>
- must be specified and set to <literal>C</literal>.
+ must be specified and set to either <literal>C</literal> or
+ <literal>C.UTF-8</literal>.
</para>
<tip>
<para>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index 4760570f6a..08a1c2538f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -289,7 +289,7 @@ PostgreSQL documentation
<para>
If <option>--locale-provider</option> is <literal>builtin</literal>,
<option>--locale</option> must be specified and set to
- <literal>C</literal>.
+ <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 6a26388bfa..85f3238eb0 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -16,6 +16,8 @@
*/
#include "catalog/pg_collation.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "utils/pg_locale.h"
/*
@@ -64,6 +66,7 @@
typedef enum
{
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
+ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
@@ -266,7 +269,12 @@ pg_set_regex_collation(Oid collation)
if (GetDatabaseEncoding() == PG_UTF8)
{
if (pg_regex_locale)
- pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ {
+ if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ pg_regex_strategy = PG_REGEX_BUILTIN;
+ else
+ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
@@ -290,6 +298,8 @@ pg_wc_isdigit(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isdigit(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -322,6 +332,8 @@ pg_wc_isalpha(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALPHA));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
@@ -354,6 +366,8 @@ pg_wc_isalnum(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalnum(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -395,6 +409,8 @@ pg_wc_isupper(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISUPPER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
@@ -427,6 +443,8 @@ pg_wc_islower(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISLOWER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
@@ -459,6 +477,8 @@ pg_wc_isgraph(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISGRAPH));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
@@ -491,6 +511,8 @@ pg_wc_isprint(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPRINT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
@@ -523,6 +545,8 @@ pg_wc_ispunct(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_ispunct(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
@@ -555,6 +579,8 @@ pg_wc_isspace(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISSPACE));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
@@ -588,6 +614,8 @@ pg_wc_toupper(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_uppercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -628,6 +656,8 @@ pg_wc_tolower(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_lowercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -792,6 +822,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
#endif
break;
+ case PG_REGEX_BUILTIN:
+ max_chr = (pg_wchar) MAX_SIMPLE_CHR;
+ break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
@@ -809,6 +842,7 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break;
default:
+ Assert(false);
max_chr = 0; /* can't get here, but keep compiler quiet */
break;
}
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 5f483b8dbc..1a578b8a2b 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -77,6 +77,8 @@
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "mb/pg_wchar.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
@@ -1679,6 +1681,33 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1799,6 +1828,33 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1920,6 +1976,73 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const unsigned char *src = (unsigned char *) buff;
+ unsigned char *dst;
+ size_t dstsize = nbytes + 1;
+ int srcoff = 0;
+ int dstoff = 0;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* Output workspace cannot have more codes than input bytes */
+ dst = (unsigned char *) palloc(dstsize);
+
+ while (srcoff < nbytes)
+ {
+ pg_wchar u1 = utf8_to_unicode(src + srcoff);
+ pg_wchar u2;
+ int u1len = unicode_utf8len(u1);
+ int u2len;
+
+ if (wasalnum)
+ u2 = unicode_lowercase_simple(u1);
+ else
+ u2 = unicode_uppercase_simple(u1);
+
+ u2len = unicode_utf8len(u2);
+
+ wasalnum = pg_u_isalnum(u2, true);
+
+ /*
+ * If we can't fit the necessary bytes and a terminating NUL,
+ * reallocate buffer to the maximum size we might need, and
+ * shrink it later.
+ */
+ if (dstoff + u2len + 1 > dstsize)
+ {
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ dstsize = (nbytes + 1) * sizeof(pg_wchar);
+ dst = repalloc(dst, dstsize);
+ }
+
+ unicode_to_utf8(u2, dst + dstoff);
+ srcoff += u1len;
+ dstoff += u2len;
+ }
+
+ *(dst + dstoff) = '\0';
+ dstoff++;
+
+ if (dstsize == dstoff)
+ {
+ result = (char *) dst;
+ }
+ else
+ {
+ /* shrink buffer and store result */
+ result = palloc(dstoff);
+ memcpy(result, dst, dstoff);
+ pfree(dst);
+ }
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 1b3fb3822b..e8b05ff155 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1593,7 +1593,7 @@ pg_newlocale_from_collation(Oid collid)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
locstr = TextDatumGetCString(datum);
- if (strcmp(locstr, "C") != 0)
+ if (strcmp(locstr, "C.UTF-8") != 0 && strcmp(locstr, "C") != 0)
elog(ERROR, "unexpected builtin locale: %s", locstr);
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
@@ -1730,7 +1730,11 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
- /* the builtin collation provider is not versioned */
+ /*
+ * The only two supported locales (C and C.UTF-8) are both based on memcmp
+ * and do not change. (The ctype behavior can change, but the versioning
+ * does not track that.)
+ */
if (collprovider == COLLPROVIDER_BUILTIN)
return NULL;
@@ -2510,6 +2514,16 @@ builtin_validate_locale(int encoding, const char *locale)
{
canonical_name = "C";
}
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "PG_UNICODE_FAST";
+ }
+ else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "C.UTF-8";
+ }
if (!canonical_name)
ereport(ERROR,
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5bb0bd65e6..22c0ad90f4 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -428,7 +428,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
datlocale = TextDatumGetCString(datum);
- if (strcmp(datlocale, "C") != 0)
+ if (strcmp(datlocale, "C.UTF-8") != 0 && strcmp(datlocale, "C") != 0)
elog(ERROR, "unexpected builtin locale: %s", datlocale);
default_locale.info.builtin.locale = MemoryContextStrdup(
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 45aef30282..be2428b8ab 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -196,6 +196,23 @@ command_ok(
],
'locale provider builtin with --locale');
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E SQL_ASCII',
+ '--builtin-locale=C.UTF-8', "$tempdir/data9"
+ ],
+ 'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
+);
+
command_ok(
[
'initdb', '--no-sync',
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index e8cb7cc60e..94bf086ba8 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -141,7 +141,7 @@ if ($oldversion >= 17)
{
$original_encoding = "UTF-8";
$original_provider = "b";
- $original_datlocale = "C";
+ $original_datlocale = "C.UTF-8";
}
elsif ($oldversion >= 15 && $ENV{with_icu} eq 'yes')
{
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index dfd635bfab..3ba623f9d1 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -139,6 +139,24 @@ $node->command_ok(
],
'create database with provider "builtin" and LC_CTYPE=C');
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E UTF-8', '--builtin-locale=C.UTF8',
+ 'tbuiltin5'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E LATIN1', '--builtin-locale=C.UTF-8',
+ 'tbuiltin6'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
$node->command_fails(
[
'createdb', '-T',
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 938432e8a4..b95a89491d 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -30,5 +30,8 @@
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
+{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
+ collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
+ colllocale => 'C.UTF-8' },
]
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
new file mode 100644
index 0000000000..33dae9569e
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8.out
@@ -0,0 +1,128 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+SET client_encoding TO UTF8;
+--
+-- Test PG_C_UTF8
+--
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+-----------------+-----------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs ßss Déf | ÁBC SßS ßSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | DŽxxdž DŽxxdž DŽxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_c_utf8;
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+ lower
+-------
+ ασ
+(1 row)
+
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+ lower
+-------
+ αͺσͺ
+(1 row)
+
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+ lower
+-------
+ α΄σ΄
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/expected/collate.utf8_1.out b/src/test/regress/expected/collate.utf8_1.out
new file mode 100644
index 0000000000..e73fdf50c3
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8_1.out
@@ -0,0 +1,8 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 1d8a414eea..e48cb4b7a3 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,9 +78,9 @@ test: brin_bloom brin_multi
# psql depends on create_am
# amutils depends on geometry, create_index_spgist, hash_index, brin
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps
-# collate.*.utf8 tests cannot be run in parallel with each other
+# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252
# ----------
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
new file mode 100644
index 0000000000..6bfdbb98c6
--- /dev/null
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -0,0 +1,59 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+SET client_encoding TO UTF8;
+
+--
+-- Test PG_C_UTF8
+--
+
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+
+DROP TABLE test_pg_c_utf8;
+
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_C_UTF8;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
--
2.34.1
[text/x-patch] v22-0004-Inline-basic-UTF-8-functions.patch (6.2K, ../../[email protected]/5-v22-0004-Inline-basic-UTF-8-functions.patch)
download | inline diff:
From 6874fd75a573bdf2720e94b41f141f8f2f122825 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 2 Mar 2024 11:27:23 -0800
Subject: [PATCH v22 4/7] Inline basic UTF-8 functions.
Shows a measurable speedup when processing UTF-8 data, such as with
the new builtin collation provider.
Discussion: https://postgr.es/m/[email protected]
---
src/common/wchar.c | 92 +------------------------------------
src/include/mb/pg_wchar.h | 96 +++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 91 deletions(-)
diff --git a/src/common/wchar.c b/src/common/wchar.c
index a238c0106c..17788ac8b8 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -476,39 +476,6 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
}
-/*
- * Map a Unicode code point to UTF-8. utf8string must have at least
- * unicode_utf8len(c) bytes available.
- */
-unsigned char *
-unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
-{
- if (c <= 0x7F)
- {
- utf8string[0] = c;
- }
- else if (c <= 0x7FF)
- {
- utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
- utf8string[1] = 0x80 | (c & 0x3F);
- }
- else if (c <= 0xFFFF)
- {
- utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
- utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[2] = 0x80 | (c & 0x3F);
- }
- else
- {
- utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
- utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
- utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[3] = 0x80 | (c & 0x3F);
- }
-
- return utf8string;
-}
-
/*
* Trivial conversion from pg_wchar to UTF-8.
* caller should allocate enough space for "to"
@@ -535,39 +502,10 @@ pg_wchar2utf_with_len(const pg_wchar *from, unsigned char *to, int len)
return cnt;
}
-/*
- * Return the byte length of a UTF8 character pointed to by s
- *
- * Note: in the current implementation we do not support UTF8 sequences
- * of more than 4 bytes; hence do NOT return a value larger than 4.
- * We return "1" for any leading byte that is either flat-out illegal or
- * indicates a length larger than we support.
- *
- * pg_utf2wchar_with_len(), utf8_to_unicode(), pg_utf8_islegal(), and perhaps
- * other places would need to be fixed to change this.
- */
int
pg_utf_mblen(const unsigned char *s)
{
- int len;
-
- if ((*s & 0x80) == 0)
- len = 1;
- else if ((*s & 0xe0) == 0xc0)
- len = 2;
- else if ((*s & 0xf0) == 0xe0)
- len = 3;
- else if ((*s & 0xf8) == 0xf0)
- len = 4;
-#ifdef NOT_USED
- else if ((*s & 0xfc) == 0xf8)
- len = 5;
- else if ((*s & 0xfe) == 0xfc)
- len = 6;
-#endif
- else
- len = 1;
- return len;
+ return utf8_mblen(s);
}
/*
@@ -670,34 +608,6 @@ ucs_wcwidth(pg_wchar ucs)
return 1;
}
-/*
- * Convert a UTF-8 character to a Unicode code point.
- * This is a one-character version of pg_utf2wchar_with_len.
- *
- * No error checks here, c must point to a long-enough string.
- */
-pg_wchar
-utf8_to_unicode(const unsigned char *c)
-{
- if ((*c & 0x80) == 0)
- return (pg_wchar) c[0];
- else if ((*c & 0xe0) == 0xc0)
- return (pg_wchar) (((c[0] & 0x1f) << 6) |
- (c[1] & 0x3f));
- else if ((*c & 0xf0) == 0xe0)
- return (pg_wchar) (((c[0] & 0x0f) << 12) |
- ((c[1] & 0x3f) << 6) |
- (c[2] & 0x3f));
- else if ((*c & 0xf8) == 0xf0)
- return (pg_wchar) (((c[0] & 0x07) << 18) |
- ((c[1] & 0x3f) << 12) |
- ((c[2] & 0x3f) << 6) |
- (c[3] & 0x3f));
- else
- /* that is an invalid code on purpose */
- return 0xffffffff;
-}
-
static int
pg_utf_dsplen(const unsigned char *s)
{
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 69a55b66f4..f0ce47977c 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -555,6 +555,102 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Return the byte length of a UTF8 character pointed to by s
+ *
+ * Note: in the current implementation we do not support UTF8 sequences
+ * of more than 4 bytes; hence do NOT return a value larger than 4.
+ * We return "1" for any leading byte that is either flat-out illegal or
+ * indicates a length larger than we support.
+ *
+ * pg_utf2wchar_with_len(), utf8_to_unicode(), pg_utf8_islegal(), and perhaps
+ * other places would need to be fixed to change this.
+ */
+static inline int
+utf8_mblen(const unsigned char *s)
+{
+ int len;
+
+ if ((*s & 0x80) == 0)
+ len = 1;
+ else if ((*s & 0xe0) == 0xc0)
+ len = 2;
+ else if ((*s & 0xf0) == 0xe0)
+ len = 3;
+ else if ((*s & 0xf8) == 0xf0)
+ len = 4;
+#ifdef NOT_USED
+ else if ((*s & 0xfc) == 0xf8)
+ len = 5;
+ else if ((*s & 0xfe) == 0xfc)
+ len = 6;
+#endif
+ else
+ len = 1;
+ return len;
+}
+
+/*
+ * Convert a UTF-8 character to a Unicode code point.
+ * This is a one-character version of pg_utf2wchar_with_len.
+ *
+ * No error checks here, c must point to a long-enough string.
+ */
+static inline pg_wchar
+utf8_to_unicode(const unsigned char *c)
+{
+ if ((*c & 0x80) == 0)
+ return (pg_wchar) c[0];
+ else if ((*c & 0xe0) == 0xc0)
+ return (pg_wchar) (((c[0] & 0x1f) << 6) |
+ (c[1] & 0x3f));
+ else if ((*c & 0xf0) == 0xe0)
+ return (pg_wchar) (((c[0] & 0x0f) << 12) |
+ ((c[1] & 0x3f) << 6) |
+ (c[2] & 0x3f));
+ else if ((*c & 0xf8) == 0xf0)
+ return (pg_wchar) (((c[0] & 0x07) << 18) |
+ ((c[1] & 0x3f) << 12) |
+ ((c[2] & 0x3f) << 6) |
+ (c[3] & 0x3f));
+ else
+ /* that is an invalid code on purpose */
+ return 0xffffffff;
+}
+
+/*
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
+ */
+static inline unsigned char *
+unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
+{
+ if (c <= 0x7F)
+ {
+ utf8string[0] = c;
+ }
+ else if (c <= 0x7FF)
+ {
+ utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
+ utf8string[1] = 0x80 | (c & 0x3F);
+ }
+ else if (c <= 0xFFFF)
+ {
+ utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
+ utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[2] = 0x80 | (c & 0x3F);
+ }
+ else
+ {
+ utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
+ utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
+ utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[3] = 0x80 | (c & 0x3F);
+ }
+
+ return utf8string;
+}
+
/*
* Number of bytes needed to represent the given char in UTF8.
*/
--
2.34.1
[text/x-patch] v22-0005-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch (9.3K, ../../[email protected]/6-v22-0005-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch)
download | inline diff:
From bb95fbc6ef9eea5d18dfe841e0be845cc76303bc Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 7 Mar 2024 12:26:02 -0800
Subject: [PATCH v22 5/7] Add unicode_strtitle() for Unicode Default Case
Conversion.
This brings the titlecasing implementation out of formatting.c and
into unicode_case.c by accepting an arbitrary word boundary callback.
Simple for now, but can be extended to support the Unicode Default
Case Conversion algorithm with full case mapping.
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 124 ++++++++++++++++-------------
src/common/unicode_case.c | 74 +++++++++++++++--
src/include/common/unicode_case.h | 5 ++
3 files changed, 141 insertions(+), 62 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 1a578b8a2b..6d5cbe2929 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1920,6 +1920,47 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
return result;
}
+struct WordBoundaryState
+{
+ const char *str;
+ size_t len;
+ size_t offset;
+ bool init;
+ bool prev_alnum;
+};
+
+/*
+ * Simple word boundary iterator that draws boundaries each time the result of
+ * pg_u_isalnum() changes.
+ */
+static size_t
+initcap_wbnext(void *state)
+{
+ struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
+
+ while (wbstate->offset < wbstate->len &&
+ wbstate->str[wbstate->offset] != '\0')
+ {
+ pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ wbstate->offset);
+ bool curr_alnum = pg_u_isalnum(u, true);
+
+ if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
+ {
+ size_t prev_offset = wbstate->offset;
+
+ wbstate->init = true;
+ wbstate->offset += unicode_utf8len(u);
+ wbstate->prev_alnum = curr_alnum;
+ return prev_offset;
+ }
+
+ wbstate->offset += unicode_utf8len(u);
+ }
+
+ return wbstate->len;
+}
+
/*
* collation-aware, wide-character-aware initcap function
*
@@ -1978,69 +2019,42 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
#endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
{
- const unsigned char *src = (unsigned char *) buff;
- unsigned char *dst;
- size_t dstsize = nbytes + 1;
- int srcoff = 0;
- int dstoff = 0;
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+ struct WordBoundaryState wbstate = {
+ .str = src,
+ .len = srclen,
+ .offset = 0,
+ .init = false,
+ .prev_alnum = false,
+ };
Assert(GetDatabaseEncoding() == PG_UTF8);
- /* Output workspace cannot have more codes than input bytes */
- dst = (unsigned char *) palloc(dstsize);
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
- while (srcoff < nbytes)
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ if (needed + 1 > dstsize)
{
- pg_wchar u1 = utf8_to_unicode(src + srcoff);
- pg_wchar u2;
- int u1len = unicode_utf8len(u1);
- int u2len;
-
- if (wasalnum)
- u2 = unicode_lowercase_simple(u1);
- else
- u2 = unicode_uppercase_simple(u1);
-
- u2len = unicode_utf8len(u2);
-
- wasalnum = pg_u_isalnum(u2, true);
-
- /*
- * If we can't fit the necessary bytes and a terminating NUL,
- * reallocate buffer to the maximum size we might need, and
- * shrink it later.
- */
- if (dstoff + u2len + 1 > dstsize)
- {
- /* Overflow paranoia */
- if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
-
- dstsize = (nbytes + 1) * sizeof(pg_wchar);
- dst = repalloc(dst, dstsize);
- }
+ /* reset iterator */
+ wbstate.offset = 0;
+ wbstate.prev_alnum = false;
- unicode_to_utf8(u2, dst + dstoff);
- srcoff += u1len;
- dstoff += u2len;
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ Assert(needed + 1 == dstsize);
}
- *(dst + dstoff) = '\0';
- dstoff++;
-
- if (dstsize == dstoff)
- {
- result = (char *) dst;
- }
- else
- {
- /* shrink buffer and store result */
- result = palloc(dstoff);
- memcpy(result, dst, dstoff);
- pfree(dst);
- }
+ result = dst;
}
else
{
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 842db173ba..0e4eb54af3 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -22,7 +22,8 @@
static const pg_case_map *find_case_map(pg_wchar ucs);
static size_t convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
- CaseKind casekind);
+ CaseKind top_casekind, WordBoundaryNext wbnext,
+ void *wbstate);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -67,7 +68,40 @@ unicode_uppercase_simple(pg_wchar code)
size_t
unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+}
+
+/*
+ * unicode_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * Titlecasing requires knowledge about word boundaries, which is provided by
+ * the callback wbnext. A word boundary is the offset of the start of a word
+ * or the offset of the character immediately following a word.
+ *
+ * The caller is expected to initialize and free the callback state
+ * wbstate. The callback should first return offset 0 for the first boundary;
+ * then the offset of each subsequent word boundary; then the total length of
+ * the string to indicate the final boundary.
+ */
+size_t
+unicode_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen,
+ WordBoundaryNext wbnext, void *wbstate)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ wbstate);
}
/*
@@ -89,20 +123,34 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen)
size_t
unicode_strupper(char *dst, size_t dstsize, const char *src, size_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
}
/*
- * Implement Unicode Default Case Conversion algorithm.
+ * If str_casekind is CaseLower or CaseUpper, map each character in the string
+ * for which a mapping is available.
*
- * Map each character in the string for which a mapping is available.
+ * If str_casekind is CaseTitle, maps characters found on a word boundary to
+ * uppercase and other characters to lowercase.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
- CaseKind casekind)
+ CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
{
+ /* character CaseKind varies while titlecasing */
+ CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
+ size_t boundary = 0;
+
+ Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
+ (str_casekind != CaseTitle && !wbnext && !wbstate));
+
+ if (str_casekind == CaseTitle)
+ {
+ boundary = wbnext(wbstate);
+ Assert(boundary == 0); /* start of text is always a boundary */
+ }
while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
{
@@ -110,9 +158,21 @@ convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
int u1len = unicode_utf8len(u1);
const pg_case_map *casemap = find_case_map(u1);
+ if (str_casekind == CaseTitle)
+ {
+ if (srcoff == boundary)
+ {
+ chr_casekind = CaseUpper;
+ boundary = wbnext(wbstate);
+ }
+ else
+ chr_casekind = CaseLower;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
if (casemap)
{
- pg_wchar u2 = casemap->simplemap[casekind];
+ pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
if (result_len + u2len < dstsize)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index ad6f62cc41..283f6cc1e4 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -16,11 +16,16 @@
#include "mb/pg_wchar.h"
+typedef size_t (*WordBoundaryNext) (void *wbstate);
+
pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
size_t srclen);
+size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
+ size_t srclen, WordBoundaryNext wbnext,
+ void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
size_t srclen);
--
2.34.1
[text/x-patch] v22-0006-Support-Unicode-full-case-mapping-and-conversion.patch (555.7K, ../../[email protected]/7-v22-0006-Support-Unicode-full-case-mapping-and-conversion.patch)
download | inline diff:
From 96d3d57e154b472f72bc0278352071cab520cee5 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 7 Mar 2024 13:10:29 -0800
Subject: [PATCH v22 6/7] Support Unicode full case mapping and conversion.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Generate tables from Unicode SpecialCasing.txt to support more
sophisticated case mapping behavior:
* support case mappings to multiple codepoints, such as "ß"
uppercasing to "SS"
* support conditional case mappings, such as the "final sigma"
* support titlecase variants, such as "dž" uppercasing to "DŽ" but
titlecasing to "Dž"
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 12 +-
src/common/unicode/Makefile | 4 +-
.../unicode/generate-unicode_case_table.pl | 161 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_case.c | 185 +-
src/include/common/unicode_case.h | 8 +-
src/include/common/unicode_case_table.h | 6094 +++++++++--------
7 files changed, 3481 insertions(+), 2987 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 6d5cbe2929..97ccf23583 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,13 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1842,13 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -2038,7 +2038,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2049,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index c38ab36b1e..87d7355794 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -30,7 +30,7 @@ update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
@@ -91,4 +91,4 @@ clean:
rm -f $(OBJS) case_test case_test.o category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
index 44b785b861..02da4b682f 100644
--- a/src/common/unicode/generate-unicode_case_table.pl
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -3,7 +3,7 @@
# Generate Unicode character case mappings. Does not include tailoring
# or locale-specific mappings.
#
-# Input: UnicodeData.txt
+# Input: SpecialCasing.txt UnicodeData.txt
# Output: unicode_case_table.h
#
# Copyright (c) 2000-2023, PostgreSQL Global Development Group
@@ -21,6 +21,10 @@ GetOptions('outdir:s' => \$output_path);
my $output_table_file = "$output_path/unicode_case_table.h";
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
my $FH;
my %simple = ();
@@ -51,6 +55,98 @@ while (my $line = <$FH>)
}
close $FH;
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
# Start writing out the output files
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
@@ -63,6 +159,8 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
$num_simple++ unless $code < 0x80;
}
+my $num_special = scalar(keys %special) + 1;
+
print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
@@ -86,6 +184,19 @@ print $OT <<"EOS";
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -94,12 +205,47 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
@@ -114,8 +260,10 @@ for (my $code = 0; $code < 0x80; $code++)
my $lc = ($simple{$code}{Simple_Lowercase} || $code);
my $tc = ($simple{$code}{Simple_Titlecase} || $code);
my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
$code, $lc, $tc, $uc;
}
printf $OT "\n";
@@ -126,9 +274,14 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
next unless $code >= 0x80; # already output above
my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
$code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
- $map->{Simple_Uppercase};
+ $map->{Simple_Uppercase}, $special_case;
}
print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index b9a4181c32..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_case_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
output: ['unicode_case_table.h'],
command: [
perl, files('generate-unicode_case_table.pl'),
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 0e4eb54af3..c920e2b4c7 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -22,8 +22,10 @@
static const pg_case_map *find_case_map(pg_wchar ucs);
static size_t convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
- CaseKind top_casekind, WordBoundaryNext wbnext,
+ CaseKind casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -64,11 +66,16 @@ unicode_uppercase_simple(pg_wchar code)
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen)
+unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, full, NULL,
+ NULL);
}
/*
@@ -87,6 +94,13 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen)
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
*
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied; use titlecase mapping for the first character;
+ * and perform adjustment to the first Cased character after a word
+ * boundary. If full is false, use only simple mappings; use uppercase mapping
+ * for the first character; and map the first character of each word to
+ * uppercase.
+ *
* Titlecasing requires knowledge about word boundaries, which is provided by
* the callback wbnext. A word boundary is the offset of the start of a word
* or the offset of the character immediately following a word.
@@ -98,9 +112,9 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen)
*/
size_t
unicode_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen,
- WordBoundaryNext wbnext, void *wbstate)
+ bool full, WordBoundaryNext wbnext, void *wbstate)
{
- return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, full, wbnext,
wbstate);
}
@@ -119,29 +133,42 @@ unicode_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen,
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strupper(char *dst, size_t dstsize, const char *src, size_t srclen)
+unicode_strupper(char *dst, size_t dstsize, const char *src, size_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, full, NULL,
+ NULL);
}
/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
* If str_casekind is CaseLower or CaseUpper, map each character in the string
* for which a mapping is available.
*
- * If str_casekind is CaseTitle, maps characters found on a word boundary to
- * uppercase and other characters to lowercase.
+ * If str_casekind is CaseTitle: for each word boundary, "adjust" forward to
+ * the next Cased character and map it to titlecase; then map subsequent
+ * characters to lowercase until the next word boundary.
+ *
+ * Some characters have special mappings, which can map a single codepoint to
+ * multiple codepoints, or depend on conditions.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
+ void *wbstate)
{
/* character CaseKind varies while titlecasing */
CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
size_t boundary = 0;
+ bool adjusting = true;
Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
(str_casekind != CaseTitle && !wbnext && !wbstate));
@@ -156,21 +183,77 @@ convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
{
pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
- const pg_case_map *casemap = find_case_map(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+ /*
+ * Titlecasing has two states: adjusting from boundary (initial
+ * state), and lowercasing until the next boundary.
+ */
if (str_casekind == CaseTitle)
{
if (srcoff == boundary)
{
- chr_casekind = CaseUpper;
+ /* reset to initial state and find the next boundary */
+ adjusting = true;
boundary = wbnext(wbstate);
}
+
+ if (adjusting)
+ {
+ if (!full || pg_u_prop_cased(u1))
+ {
+ /* adjustment done: map to titlecase */
+ adjusting = false;
+ chr_casekind = full ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else
+ casemap = NULL; /* no mapping during adjustment */
+ }
else
+ {
chr_casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Note: only a single special mapping per codepoint is currently
+ * supported, though Unicode allows for multiple special mappings for
+ * a single codepoint.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
}
/* perform mapping, update result_len, and write to dst */
- if (casemap)
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[chr_casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
{
pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
@@ -198,6 +281,82 @@ convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
return result_len;
}
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
/* find entry in simple case map, if any */
static const pg_case_map *
find_case_map(pg_wchar ucs)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index 283f6cc1e4..7cc970ba54 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -22,11 +22,11 @@ pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
- size_t srclen);
+ size_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
- size_t srclen, WordBoundaryNext wbnext,
- void *wbstate);
+ size_t srclen, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
- size_t srclen);
+ size_t srclen, bool full);
#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
index b239f0b3c3..081d4133b1 100644
--- a/src/include/common/unicode_case_table.h
+++ b/src/include/common/unicode_case_table.h
@@ -20,6 +20,19 @@
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -28,2974 +41,3143 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
*/
-static const pg_case_map case_map[2955] =
+static const pg_case_map case_map[3003] =
{
/* begin dense entries for codepoints < 0x80 */
- {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}},
- {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}},
- {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}},
- {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}},
- {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}},
- {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}},
- {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}},
- {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}},
- {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}},
- {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}},
- {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}},
- {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}},
- {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}},
- {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}},
- {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}},
- {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}},
- {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}},
- {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}},
- {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}},
- {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}},
- {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}},
- {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}},
- {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}},
- {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}},
- {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}},
- {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}},
- {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}},
- {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}},
- {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}},
- {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}},
- {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}},
- {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}},
- {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}},
- {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}},
- {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}},
- {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}},
- {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}},
- {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}},
- {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}},
- {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}},
- {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}},
- {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}},
- {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}},
- {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}},
- {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}},
- {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}},
- {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}},
- {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}},
- {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}},
- {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}},
- {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}},
- {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}},
- {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}},
- {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}},
- {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}},
- {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}},
- {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}},
- {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}},
- {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}},
- {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}},
- {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}},
- {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}},
- {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}},
- {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}},
- {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}},
- {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}},
- {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}},
- {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}},
- {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}},
- {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}},
- {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}},
- {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}},
- {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}},
- {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}},
- {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}},
- {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}},
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
/* begin sparse entries for codepoints >= 0x80 */
- {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}},
- {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}},
- {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}},
- {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}},
- {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}},
- {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}},
- {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}},
- {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}},
- {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}},
- {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}},
- {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}},
- {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}},
- {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}},
- {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}},
- {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}},
- {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}},
- {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}},
- {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}},
- {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}},
- {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}},
- {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}},
- {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}},
- {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}},
- {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}},
- {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}},
- {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}},
- {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}},
- {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}},
- {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}},
- {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}},
- {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}},
- {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}},
- {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}},
- {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}},
- {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}},
- {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}},
- {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}},
- {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}},
- {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}},
- {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}},
- {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}},
- {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}},
- {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}},
- {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}},
- {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}},
- {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}},
- {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}},
- {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}},
- {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}},
- {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}},
- {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}},
- {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}},
- {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}},
- {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}},
- {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}},
- {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}},
- {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}},
- {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}},
- {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}},
- {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}},
- {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}},
- {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}},
- {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}},
- {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}},
- {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}},
- {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}},
- {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}},
- {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}},
- {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}},
- {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}},
- {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}},
- {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}},
- {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}},
- {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}},
- {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}},
- {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}},
- {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}},
- {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}},
- {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}},
- {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}},
- {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}},
- {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}},
- {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}},
- {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}},
- {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}},
- {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}},
- {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}},
- {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}},
- {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}},
- {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}},
- {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}},
- {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}},
- {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}},
- {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}},
- {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}},
- {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}},
- {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}},
- {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}},
- {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
- {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
};
--
2.34.1
[text/x-patch] v22-0007-Add-PG_UNICODE_FAST-locale-to-the-builtin-collat.patch (16.9K, ../../[email protected]/8-v22-0007-Add-PG_UNICODE_FAST-locale-to-the-builtin-collat.patch)
download | inline diff:
From dac73acaffd465c7280a35546abfea4572ccb902 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 18:15:33 -0800
Subject: [PATCH v22 7/7] Add PG_UNICODE_FAST locale to the builtin collation
provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The PG_UNICODE_FAST locale uses code point sort order (fast,
memcmp-based) combined with Unicode character semantics. The character
semantics are based on Unicode full case mapping.
Full case mapping can map a single codepoint to multiple codepoints,
such as "ß" uppercasing to "SS". Additionally, it handles
context-sensitive mappings like the "final sigma", and it uses
titlecase mappings such as "Dž" when titlecasing (rather than plain
uppercase mappings).
Importantly, the uppercasing of "ß" as "SS" is specifically mentioned
by the SQL standard. In Postgres, UCS_BASIC uses plain ASCII semantics
for case mapping and pattern matching, so if we changed it to use the
PG_UNICODE_FAST locale, it would offer better compliance with the
standard. For now, though, do not change the behavior of UCS_BASIC.
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 17 +++
src/backend/regex/regc_pg_locale.c | 11 +-
src/backend/utils/adt/formatting.c | 22 ++-
src/backend/utils/adt/pg_locale.c | 11 +-
src/backend/utils/init/postinit.c | 11 +-
src/include/catalog/pg_collation.dat | 3 +
src/include/utils/pg_locale.h | 1 +
src/test/regress/expected/collate.utf8.out | 155 +++++++++++++++++++++
src/test/regress/sql/collate.utf8.sql | 55 ++++++++
9 files changed, 274 insertions(+), 12 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 08b534db98..9879260782 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -876,6 +876,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_unicode_fast</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. It is only
+ available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>pg_c_utf8</literal></term>
<listitem>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 85f3238eb0..24c5200cef 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -78,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -271,7 +273,10 @@ pg_set_regex_collation(Oid collation)
if (pg_regex_locale)
{
if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = !pg_regex_locale->info.builtin.casemap_full;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
}
@@ -299,7 +304,7 @@ pg_wc_isdigit(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
case PG_REGEX_BUILTIN:
- return pg_u_isdigit(c, true);
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -367,7 +372,7 @@ pg_wc_isalnum(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
case PG_REGEX_BUILTIN:
- return pg_u_isalnum(c, true);
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -546,7 +551,7 @@ pg_wc_ispunct(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
case PG_REGEX_BUILTIN:
- return pg_u_ispunct(c, true);
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 97ccf23583..47601e75ba 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,15 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1844,15 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1927,6 +1931,7 @@ struct WordBoundaryState
size_t offset;
bool init;
bool prev_alnum;
+ bool posix;
};
/*
@@ -1943,7 +1948,7 @@ initcap_wbnext(void *state)
{
pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
- bool curr_alnum = pg_u_isalnum(u, true);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
{
@@ -2030,6 +2035,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
.offset = 0,
.init = false,
.prev_alnum = false,
+ .posix = !mylocale->info.builtin.casemap_full,
};
Assert(GetDatabaseEncoding() == PG_UTF8);
@@ -2038,7 +2044,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2056,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index e8b05ff155..bc2c48e177 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1593,7 +1593,16 @@ pg_newlocale_from_collation(Oid collid)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
locstr = TextDatumGetCString(datum);
- if (strcmp(locstr, "C.UTF-8") != 0 && strcmp(locstr, "C") != 0)
+ if (strcmp(locstr, "PG_UNICODE_FAST") == 0)
+ {
+ result.info.builtin.casemap_full = true;
+ }
+ else if (strcmp(locstr, "C") == 0 ||
+ strcmp(locstr, "C.UTF-8") == 0)
+ {
+ result.info.builtin.casemap_full = false;
+ }
+ else
elog(ERROR, "unexpected builtin locale: %s", locstr);
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 22c0ad90f4..f06d849463 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -428,7 +428,16 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
datlocale = TextDatumGetCString(datum);
- if (strcmp(datlocale, "C.UTF-8") != 0 && strcmp(datlocale, "C") != 0)
+ if (strcmp(datlocale, "PG_UNICODE_FAST") == 0)
+ {
+ default_locale.info.builtin.casemap_full = true;
+ }
+ else if (strcmp(datlocale, "C") == 0 ||
+ strcmp(datlocale, "C.UTF-8") == 0)
+ {
+ default_locale.info.builtin.casemap_full = false;
+ }
+ else
elog(ERROR, "unexpected builtin locale: %s", datlocale);
default_locale.info.builtin.locale = MemoryContextStrdup(
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index b95a89491d..a187b3dcef 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -33,5 +33,8 @@
{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
colllocale => 'C.UTF-8' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST' },
]
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 2fd0c5157b..b5b1ed45e8 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -79,6 +79,7 @@ struct pg_locale_struct
struct
{
const char *locale;
+ bool casemap_full;
} builtin;
locale_t lt;
#ifdef USE_ICU
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index 33dae9569e..beb08d4c4e 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -126,3 +126,158 @@ SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
t
(1 row)
+--
+-- Test PG_UNICODE_FAST
+--
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123Abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_unicode_fast;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index 6bfdbb98c6..a9ea6c7955 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -57,3 +57,58 @@ SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
SELECT 'Δ' ~* '[α-λ]' COLLATE PG_C_UTF8;
SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+
+--
+-- Test PG_UNICODE_FAST
+--
+
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+
+DROP TABLE test_pg_unicode_fast;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[α-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-12 08:24 ` Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-12 08:24 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 08.03.24 02:00, Jeff Davis wrote:
> And here's v22 (I didn't post v21).
>
> I committed Unicode property tables and functions, and the simple case
> mapping. I separated out the full case mapping changes (based on
> SpecialCasing.txt) into patch 0006.
> 0002: Basic builtin collation provider that only supports "C".
Overall, this patch looks sound.
In the documentation, let's make the list of locale providers an actual
list instead of a sequence of <sect3>s.
We had some discussion on initdb option --builtin-locale and whether it
should be something more general. I'm ok with leaving it like this for
now and maybe consider as an "open item" for PG17.
In
errmsg("parameter \"locale\" must be specified")
make "locale" a placeholder. (See commit 36a14afc076).
It seems the builtin provider accepts both "C" and "POSIX" as locale
names, but the documentation says it must be "C". Maybe we don't need
to accept "POSIX"? (Seeing that there are no plans for "POSIX.UTF-8",
maybe we just ignore the "POSIX" spelling altogether?)
Speaking of which, the code in postinit.c is inconsistent in that
respect with builtin_validate_locale(). Shouldn't postinit.c use
builtin_validate_locale(), to keep it consistent?
Or, there could be a general function that accepts a locale provider and
a locale string and validates everything together?
In initdb.c, this message
printf(_("The database cluster will be initialized with no locale.\n"));
sounds a bit confusing. I think it's ok to show "C" as a locale. I'm
not sure we need to change the logic here.
Also in initdb.c, this message
pg_fatal("locale must be specified unless provider is libc");
should be flipped around, like
locale must be specified if provider is %s
In pg_dump.c, dumpDatabase(), there are some new warning messages that
are not specifically about the builtin provider. Are those existing
deficiencies? It's not clear to me.
What are the changes in the pg_upgrade test about? Maybe explain the
scenario it is trying to test briefly?
> 0004: Inline some UTF-8 functions to improve performance
Makes sense that inlining can be effective here. But why aren't you
just inlining the existing function pg_utf_mblen()? Now we have two
functions that do the same thing. And the comment at pg_utf_mblen() is
removed completely, so it's not clear anymore why it exists.
> 0005: Add a unicode_strtitle() function and move the implementation for
> the builtin provider out of formatting.c.
In the recent discussion you had expression some uncertainty about the
detailed semantics of this. INITCAP() was copied from Oracle, so we
could check there for reference, too. Or we go with full Unicode
semantics. I'm not clear on all the differences and tradeoffs, if there
are any. In any case, it would be good if there were documentation or a
comment that somehow wrote down the resolution of this.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-03-13 07:44 ` Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-13 07:44 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Tue, 2024-03-12 at 09:24 +0100, Peter Eisentraut wrote:
> In the documentation, let's make the list of locale providers an
> actual
> list instead of a sequence of <sect3>s.
Done.
> We had some discussion on initdb option --builtin-locale and whether
> it
> should be something more general. I'm ok with leaving it like this
> for
> now and maybe consider as an "open item" for PG17.
OK.
> In
>
> errmsg("parameter \"locale\" must be specified")
>
> make "locale" a placeholder. (See commit 36a14afc076).
Done.
> It seems the builtin provider accepts both "C" and "POSIX" as locale
> names, but the documentation says it must be "C". Maybe we don't
> need
> to accept "POSIX"? (Seeing that there are no plans for "POSIX.UTF-
> 8",
> maybe we just ignore the "POSIX" spelling altogether?)
Agreed, removed "POSIX".
> Speaking of which, the code in postinit.c is inconsistent in that
> respect with builtin_validate_locale(). Shouldn't postinit.c use
> builtin_validate_locale(), to keep it consistent?
Agreed, done.
> Or, there could be a general function that accepts a locale provider
> and
> a locale string and validates everything together?
That's a good idea -- perhaps a separate cleanup patch?
> In initdb.c, this message
>
> printf(_("The database cluster will be initialized with no
> locale.\n"));
>
> sounds a bit confusing. I think it's ok to show "C" as a locale.
> I'm
> not sure we need to change the logic here.
Agreed, removed.
> Also in initdb.c, this message
>
> pg_fatal("locale must be specified unless provider is libc");
>
> should be flipped around, like
>
> locale must be specified if provider is %s
Done.
> In pg_dump.c, dumpDatabase(), there are some new warning messages
> that
> are not specifically about the builtin provider. Are those existing
> deficiencies? It's not clear to me.
I wouldn't call that a deficiency, but it seemed to be a convenient
place to do some extra sanity checking along with the minor
reorganization I did in that area.
> What are the changes in the pg_upgrade test about? Maybe explain the
> scenario it is trying to test briefly?
It's trying to be a better test for commit 9637badd9f, which eliminates
needless locale incompatibilities when performing a pg_upgrade.
At the time of that commit, the options for testing were fairly
limited, so I'm just expanding on that here a bit. It might be slightly
over-engineered? I added some comments and cleaned it up.
> > 0004: Inline some UTF-8 functions to improve performance
>
> Makes sense that inlining can be effective here. But why aren't you
> just inlining the existing function pg_utf_mblen()? Now we have two
> functions that do the same thing. And the comment at pg_utf_mblen()
> is
> removed completely, so it's not clear anymore why it exists.
I was trying to figure out what to do about USE_PRIVATE_ENCODING_FUNCS.
If libpq exports pg_utf_mblen(), it needs to continue to export that,
or else it's an ABI break, right? So that means we need at least one
extern copy of the function. See b6c7cfac88.
Though now that I look at it, I'm not even calling the inlined version
from my code -- I must have been using it in an earlier version and now
not. So I just left pg_utf_mblen() alone, and inlined unicode_to_utf8()
and utf8_to_unicode().
> > 0005: Add a unicode_strtitle() function and move the implementation
> > for
> > the builtin provider out of formatting.c.
>
> In the recent discussion you had expression some uncertainty about
> the
> detailed semantics of this. INITCAP() was copied from Oracle, so we
> could check there for reference, too. Or we go with full Unicode
> semantics. I'm not clear on all the differences and tradeoffs, if
> there
> are any. In any case, it would be good if there were documentation
> or a
> comment that somehow wrote down the resolution of this.
There are a few nuances that are different between the Unicode way to
titlecase a string and INITCAP():
1. For the initial character in a word, Unicode uses the titlecase
mapping, whereas INITCAP (as the name suggests) uses the uppercase
mapping.
2. Unicode uses full case mapping, which can change the length of the
string (e.g. mapping "ß" to the titlecase "Ss" -- though I've heard
that titlecasing "ß" doesn't make a lot of sense in German because
words typically don't begin with it). Full case mapping can also handle
context-sensitive mappings, such as the "final sigma".
3. Unicode has a lot to say about word boundaries, whereas INITCAP()
just uses the boundary between alnum and !alnum.
The unicode_strtitle() function is just a way to unify those
differences into one implementation. A "full" parameter controls
behaviors 1 & 2, and a callback handles 3. If we just want to keep it
simple, we can leave it as the character-by-character algorithm in
formatting.c.
My uncertainty was whether we really want INITCAP to be doing these
more sophisticated titlecasing transformations, or whether that should
be a separate sql function (title()? titlecase()?), or whether we just
don't need that functionality.
New series attached. I plan to commit 0001 very soon.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v23-0001-Introduce-collation-provider-builtin.patch (58.8K, ../../[email protected]/2-v23-0001-Introduce-collation-provider-builtin.patch)
download | inline diff:
From 46766448d3d9eea75bbfbd2d9080d45af398dcaa Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Mon, 1 May 2023 15:38:29 -0700
Subject: [PATCH v23 1/6] Introduce collation provider "builtin".
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
----- CATVERSION -----
Initially, the only locale supported by the builtin provider is "C",
which has identical implementation and semantics as the libc
provider's "C" locale.
The builtin provider has one additional capability that libc does not
offer: its locale is entirely independent of the server environment
variables LC_COLLATE and LC_CTYPE. That means that the collation
locale can be "C" while LC_COLLATE and LC_CTYPE are set to "en_US".
By offering a new builtin provider, it clarifies that the semantics
will never depend on libc, and makes it easier to document the
behavior.
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/ff4c2f2f9c8fc7ca27c1c24ae37ecaeaeaff6b53.camel%40j-davis.com
Reviewed-by: Daniel Vérité, Peter Eisentraut, Jeremy Schneider
---
doc/src/sgml/charset.sgml | 90 ++++++++++++++----
doc/src/sgml/ref/create_collation.sgml | 11 ++-
doc/src/sgml/ref/create_database.sgml | 7 +-
doc/src/sgml/ref/createdb.sgml | 2 +-
doc/src/sgml/ref/initdb.sgml | 17 +++-
src/backend/catalog/pg_collation.c | 5 +-
src/backend/commands/collationcmds.c | 94 +++++++++++++++----
src/backend/commands/dbcommands.c | 121 ++++++++++++++++++++-----
src/backend/utils/adt/formatting.c | 6 ++
src/backend/utils/adt/pg_locale.c | 119 ++++++++++++++++++++----
src/backend/utils/init/postinit.c | 20 +++-
src/bin/initdb/initdb.c | 39 +++++---
src/bin/initdb/t/001_initdb.pl | 40 +++++++-
src/bin/pg_dump/pg_dump.c | 49 ++++++----
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 81 +++++++++++++----
src/bin/psql/describe.c | 4 +-
src/bin/scripts/createdb.c | 18 +++-
src/bin/scripts/t/020_createdb.pl | 60 ++++++++++++
src/include/catalog/pg_collation.dat | 6 +-
src/include/catalog/pg_collation.h | 3 +
src/include/utils/pg_locale.h | 6 +-
src/test/icu/t/010_database.pl | 22 ++---
src/test/regress/expected/collate.out | 19 +++-
src/test/regress/sql/collate.sql | 8 ++
24 files changed, 689 insertions(+), 158 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 4fc143025e..7114eb7b52 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -342,22 +342,14 @@ initdb --locale=sv_SE
<title>Locale Providers</title>
<para>
- <productname>PostgreSQL</productname> supports multiple <firstterm>locale
- providers</firstterm>. This specifies which library supplies the locale
- data. One standard provider name is <literal>libc</literal>, which uses
- the locales provided by the operating system C library. These are the
- locales used by most tools provided by the operating system. Another
- provider is <literal>icu</literal>, which uses the external
- ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can
- only be used if support for ICU was configured when PostgreSQL was built.
+ A locale provider specifies which library defines the locale behavior for
+ collations and character classifications.
</para>
<para>
The commands and tools that select the locale settings, as described
- above, each have an option to select the locale provider. The examples
- shown earlier all use the <literal>libc</literal> provider, which is the
- default. Here is an example to initialize a database cluster using the
- ICU provider:
+ above, each have an option to select the locale provider. Here is an
+ example to initialize a database cluster using the ICU provider:
<programlisting>
initdb --locale-provider=icu --icu-locale=en
</programlisting>
@@ -370,12 +362,76 @@ initdb --locale-provider=icu --icu-locale=en
</para>
<para>
- Which locale provider to use depends on individual requirements. For most
- basic uses, either provider will give adequate results. For the libc
- provider, it depends on what the operating system offers; some operating
- systems are better than others. For advanced uses, ICU offers more locale
- variants and customization options.
+ Regardless of the locale provider, the operating system is still used to
+ provide some locale-aware behavior, such as messages (see <xref
+ linkend="guc-lc-messages"/>).
</para>
+
+ <para>
+ The available locale providers are listed below:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>builtin</literal></term>
+ <listitem>
+ <para>
+ The <literal>builtin</literal> provider uses built-in operations. Only
+ the <literal>C</literal> locale is supported for this provider.
+ </para>
+ <para>
+ The <literal>C</literal> locale behavior is identical to the
+ <literal>C</literal> locale in the libc provider. When using this
+ locale, the behavior may depend on the database encoding.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>icu</literal></term>
+ <listitem>
+ <para>
+ The <literal>icu</literal> provider uses the external
+ ICU<indexterm><primary>ICU</primary></indexterm>
+ library. <productname>PostgreSQL</productname> must have been
+ configured with support.
+ </para>
+ <para>
+ ICU provides collation and character classification behavior that is
+ independent of the operating system and database encoding, which is
+ preferable if you expect to transition to other platforms without any
+ change in results. <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal> can be set independently of the ICU
+ locale.
+ </para>
+ <note>
+ <para>
+ For the ICU provider, results may depend on the version of the ICU
+ library used, as it is updated to reflect changes in natural language
+ over time.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>libc</literal></term>
+ <listitem>
+ <para>
+ The <literal>libc</literal> provider uses the operating system's C
+ library. The collation and character classification behavior is
+ controlled by the settings <literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal>, so they cannot be set independently.
+ </para>
+ <note>
+ <para>
+ The same locale name may have different behavior on different
+ platforms when using the libc provider.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</sect2>
<sect2 id="icu-locales">
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 5cf9777764..98cd7d56be 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -96,6 +96,11 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<replaceable>locale</replaceable>, you cannot specify either of those
parameters.
</para>
+ <para>
+ If <replaceable>provider</replaceable> is <literal>builtin</literal>,
+ then <replaceable>locale</replaceable> must be specified and set to
+ <literal>C</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -129,9 +134,9 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<listitem>
<para>
Specifies the provider to use for locale services associated with this
- collation. Possible values are
- <literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
- (if the server was built with ICU support) or <literal>libc</literal>.
+ collation. Possible values are <literal>builtin</literal>,
+ <literal>icu</literal><indexterm><primary>ICU</primary></indexterm> (if
+ the server was built with ICU support) or <literal>libc</literal>.
<literal>libc</literal> is the default. See <xref
linkend="locale-providers"/> for details.
</para>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 72927960eb..6c1fd95602 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -162,6 +162,11 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
linkend="create-database-lc-ctype"/>, or <xref
linkend="create-database-icu-locale"/> individually.
</para>
+ <para>
+ If <xref linkend="create-database-locale-provider"/> is
+ <literal>builtin</literal>, then <replaceable>locale</replaceable>
+ must be specified and set to <literal>C</literal>.
+ </para>
<tip>
<para>
The other locale settings <xref linkend="guc-lc-messages"/>, <xref
@@ -243,7 +248,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<listitem>
<para>
Specifies the provider to use for the default collation in this
- database. Possible values are
+ database. Possible values are <literal>builtin</literal>,
<literal>icu</literal><indexterm><primary>ICU</primary></indexterm>
(if the server was built with ICU support) or <literal>libc</literal>.
By default, the provider is the same as that of the <xref
diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml
index e4647d5ce7..d3e815f659 100644
--- a/doc/src/sgml/ref/createdb.sgml
+++ b/doc/src/sgml/ref/createdb.sgml
@@ -171,7 +171,7 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
Specifies the locale provider for the database's default collation.
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index cd75cae10e..4760570f6a 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -286,6 +286,11 @@ PostgreSQL documentation
environment that <command>initdb</command> runs in. Locale
support is described in <xref linkend="locale"/>.
</para>
+ <para>
+ If <option>--locale-provider</option> is <literal>builtin</literal>,
+ <option>--locale</option> must be specified and set to
+ <literal>C</literal>.
+ </para>
</listitem>
</varlistentry>
@@ -314,8 +319,18 @@ PostgreSQL documentation
</listitem>
</varlistentry>
+ <varlistentry id="app-initdb-builtin-locale">
+ <term><option>--builtin-locale=<replaceable>locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the locale name when the builtin provider is used. Locale support
+ is described in <xref linkend="locale"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="app-initdb-option-locale-provider">
- <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <term><option>--locale-provider={<literal>builtin</literal>|<literal>libc</literal>|<literal>icu</literal>}</option></term>
<listitem>
<para>
This option sets the locale provider for databases created in the new
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index e42f2afccb..7f2f701229 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -64,7 +64,10 @@ CollationCreate(const char *collname, Oid collnamespace,
Assert(collname);
Assert(collnamespace);
Assert(collowner);
- Assert((collcollate && collctype) || colllocale);
+ Assert((collprovider == COLLPROVIDER_LIBC &&
+ collcollate && collctype && !colllocale) ||
+ (collprovider != COLLPROVIDER_LIBC &&
+ !collcollate && !collctype && colllocale));
/*
* Make sure there is no existing collation of same name & encoding.
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 59d7e17804..44675fa9da 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -66,7 +66,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
DefElem *versionEl = NULL;
char *collcollate;
char *collctype;
- char *colllocale;
+ const char *colllocale;
char *collicurules;
bool collisdeterministic;
int collencoding;
@@ -213,7 +213,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (collproviderstr)
{
- if (pg_strcasecmp(collproviderstr, "icu") == 0)
+ if (pg_strcasecmp(collproviderstr, "builtin") == 0)
+ collprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(collproviderstr, "icu") == 0)
collprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(collproviderstr, "libc") == 0)
collprovider = COLLPROVIDER_LIBC;
@@ -243,7 +245,18 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (lcctypeEl)
collctype = defGetString(lcctypeEl);
- if (collprovider == COLLPROVIDER_LIBC)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ if (!colllocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("parameter \"%s\" must be specified",
+ "locale")));
+
+ colllocale = builtin_validate_locale(GetDatabaseEncoding(),
+ colllocale);
+ }
+ else if (collprovider == COLLPROVIDER_LIBC)
{
if (!collcollate)
ereport(ERROR,
@@ -303,7 +316,17 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
- if (collprovider == COLLPROVIDER_ICU)
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * Behavior may be different in different encodings, so set
+ * collencoding to the current database encoding. No validation is
+ * required, because the "builtin" provider is compatible with any
+ * encoding.
+ */
+ collencoding = GetDatabaseEncoding();
+ }
+ else if (collprovider == COLLPROVIDER_ICU)
{
#ifdef USE_ICU
/*
@@ -332,7 +355,18 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
}
if (!collversion)
- collversion = get_collation_actual_version(collprovider, collprovider == COLLPROVIDER_ICU ? colllocale : collcollate);
+ {
+ const char *locale;
+
+ if (collprovider == COLLPROVIDER_ICU)
+ locale = colllocale;
+ else if (collprovider == COLLPROVIDER_LIBC)
+ locale = collcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ collversion = get_collation_actual_version(collprovider, locale);
+ }
newoid = CollationCreate(collName,
collNamespace,
@@ -407,6 +441,7 @@ AlterCollation(AlterCollationStmt *stmt)
Form_pg_collation collForm;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
ObjectAddress address;
@@ -433,8 +468,20 @@ AlterCollation(AlterCollationStmt *stmt)
datum = SysCacheGetAttr(COLLOID, tup, Anum_pg_collation_collversion, &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tup, collForm->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- newversion = get_collation_actual_version(collForm->collprovider, TextDatumGetCString(datum));
+ if (collForm->collprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (collForm->collprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, tup, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(collForm->collprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -498,11 +545,18 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_database) GETSTRUCT(dbtup))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_database_datlocale : Anum_pg_database_datcollate);
-
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, dbtup, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(dbtup);
}
@@ -519,11 +573,19 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
provider = ((Form_pg_collation) GETSTRUCT(colltp))->collprovider;
Assert(provider != COLLPROVIDER_DEFAULT);
- datum = SysCacheGetAttrNotNull(COLLOID, colltp,
- provider == COLLPROVIDER_ICU ?
- Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
- locale = TextDatumGetCString(datum);
+ if (provider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_colllocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (provider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(COLLOID, colltp, Anum_pg_collation_collcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
ReleaseSysCache(colltp);
}
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 0f27d7b14c..aaa2e54f21 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -697,6 +697,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
DefElem *dtemplate = NULL;
DefElem *dencoding = NULL;
DefElem *dlocale = NULL;
+ DefElem *dbuiltinlocale = NULL;
DefElem *dcollate = NULL;
DefElem *dctype = NULL;
DefElem *diculocale = NULL;
@@ -712,7 +713,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
const char *dbtemplate = NULL;
char *dbcollate = NULL;
char *dbctype = NULL;
- char *dblocale = NULL;
+ const char *dblocale = NULL;
char *dbicurules = NULL;
char dblocprovider = '\0';
char *canonname;
@@ -761,6 +762,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errorConflictingDefElem(defel, pstate);
dlocale = defel;
}
+ else if (strcmp(defel->defname, "builtin_locale") == 0)
+ {
+ if (dbuiltinlocale)
+ errorConflictingDefElem(defel, pstate);
+ dbuiltinlocale = defel;
+ }
else if (strcmp(defel->defname, "lc_collate") == 0)
{
if (dcollate)
@@ -896,7 +903,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
dbcollate = defGetString(dlocale);
dbctype = defGetString(dlocale);
+ dblocale = defGetString(dlocale);
}
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ dblocale = defGetString(dbuiltinlocale);
if (dcollate && dcollate->arg)
dbcollate = defGetString(dcollate);
if (dctype && dctype->arg)
@@ -909,7 +919,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
{
char *locproviderstr = defGetString(dlocprovider);
- if (pg_strcasecmp(locproviderstr, "icu") == 0)
+ if (pg_strcasecmp(locproviderstr, "builtin") == 0)
+ dblocprovider = COLLPROVIDER_BUILTIN;
+ else if (pg_strcasecmp(locproviderstr, "icu") == 0)
dblocprovider = COLLPROVIDER_ICU;
else if (pg_strcasecmp(locproviderstr, "libc") == 0)
dblocprovider = COLLPROVIDER_LIBC;
@@ -1026,14 +1038,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = src_ctype;
if (dblocprovider == '\0')
dblocprovider = src_locprovider;
- if (dblocale == NULL && dblocprovider == COLLPROVIDER_ICU)
- {
- if (dlocale && dlocale->arg)
- dblocale = defGetString(dlocale);
- else
- dblocale = src_locale;
- }
- if (dbicurules == NULL && dblocprovider == COLLPROVIDER_ICU)
+ if (dblocale == NULL)
+ dblocale = src_locale;
+ if (dbicurules == NULL)
dbicurules = src_icurules;
/* Some encodings are client only */
@@ -1058,6 +1065,27 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
check_encoding_locale_matches(encoding, dbcollate, dbctype);
+ if (dblocprovider == COLLPROVIDER_BUILTIN)
+ {
+ /*
+ * This would happen if template0 uses the libc provider but the new
+ * database uses builtin.
+ */
+ if (!dblocale)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("LOCALE or BUILTIN_LOCALE must be specified")));
+
+ dblocale = builtin_validate_locale(encoding, dblocale);
+ }
+ else
+ {
+ if (dbuiltinlocale && dbuiltinlocale->arg)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("BUILTIN_LOCALE cannot be specified unless locale provider is builtin")));
+ }
+
if (dblocprovider == COLLPROVIDER_ICU)
{
if (!(is_encoding_supported_by_icu(encoding)))
@@ -1099,7 +1127,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
}
else
{
- if (dblocale)
+ if (diculocale && diculocale->arg)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("ICU locale cannot be specified unless locale provider is ICU")));
@@ -1110,6 +1138,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errmsg("ICU rules cannot be specified unless locale provider is ICU")));
}
+ /* for libc, locale comes from datcollate and datctype */
+ if (dblocprovider == COLLPROVIDER_LIBC)
+ dblocale = NULL;
+
/*
* Check that the new encoding and locale settings match the source
* database. We insist on this because we simply copy the source data ---
@@ -1195,8 +1227,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if (src_collversion && !dcollversion)
{
char *actual_versionstr;
+ const char *locale;
- actual_versionstr = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ actual_versionstr = get_collation_actual_version(dblocprovider, locale);
if (!actual_versionstr)
ereport(ERROR,
(errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
@@ -1224,7 +1264,18 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* collation version, which is normally only the case for template0.
*/
if (dbcollversion == NULL)
- dbcollversion = get_collation_actual_version(dblocprovider, dblocprovider == COLLPROVIDER_ICU ? dblocale : dbcollate);
+ {
+ const char *locale;
+
+ if (dblocprovider == COLLPROVIDER_ICU)
+ locale = dblocale;
+ else if (dblocprovider == COLLPROVIDER_LIBC)
+ locale = dbcollate;
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ dbcollversion = get_collation_actual_version(dblocprovider, locale);
+ }
/* Resolve default tablespace for new database */
if (dtablespacename && dtablespacename->arg)
@@ -1363,8 +1414,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
* block on the unique index, and fail after we commit).
*/
- Assert((dblocprovider == COLLPROVIDER_ICU && dblocale) ||
- (dblocprovider != COLLPROVIDER_ICU && !dblocale));
+ Assert((dblocprovider != COLLPROVIDER_LIBC && dblocale) ||
+ (dblocprovider == COLLPROVIDER_LIBC && !dblocale));
/* Form tuple */
new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
@@ -2445,6 +2496,7 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
ObjectAddress address;
Datum datum;
bool isnull;
+ char *locale;
char *oldversion;
char *newversion;
@@ -2471,10 +2523,24 @@ AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)
datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
oldversion = isnull ? NULL : TextDatumGetCString(datum);
- datum = heap_getattr(tuple, datForm->datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
- if (isnull)
- elog(ERROR, "unexpected null in pg_database");
- newversion = get_collation_actual_version(datForm->datlocprovider, TextDatumGetCString(datum));
+ if (datForm->datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datlocale, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datForm->datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = heap_getattr(tuple, Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
+ if (isnull)
+ elog(ERROR, "unexpected null in pg_database");
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ newversion = get_collation_actual_version(datForm->datlocprovider, locale);
/* cannot change from NULL to non-NULL or vice versa */
if ((!oldversion && newversion) || (oldversion && !newversion))
@@ -2659,6 +2725,7 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
HeapTuple tp;
char datlocprovider;
Datum datum;
+ char *locale;
char *version;
tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
@@ -2669,8 +2736,20 @@ pg_database_collation_actual_version(PG_FUNCTION_ARGS)
datlocprovider = ((Form_pg_database) GETSTRUCT(tp))->datlocprovider;
- datum = SysCacheGetAttrNotNull(DATABASEOID, tp, datlocprovider == COLLPROVIDER_ICU ? Anum_pg_database_datlocale : Anum_pg_database_datcollate);
- version = get_collation_actual_version(datlocprovider, TextDatumGetCString(datum));
+ if (datlocprovider == COLLPROVIDER_ICU)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datlocale);
+ locale = TextDatumGetCString(datum);
+ }
+ else if (datlocprovider == COLLPROVIDER_LIBC)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp, Anum_pg_database_datcollate);
+ locale = TextDatumGetCString(datum);
+ }
+ else
+ locale = NULL; /* COLLPROVIDER_BUILTIN */
+
+ version = get_collation_actual_version(datlocprovider, locale);
ReleaseSysCache(tp);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 036a463491..5f483b8dbc 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1680,6 +1680,8 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
else
#endif
{
+ Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
+
if (pg_database_encoding_max_length() > 1)
{
wchar_t *workspace;
@@ -1798,6 +1800,8 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
else
#endif
{
+ Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
+
if (pg_database_encoding_max_length() > 1)
{
wchar_t *workspace;
@@ -1917,6 +1921,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
else
#endif
{
+ Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
+
if (pg_database_encoding_max_length() > 1)
{
wchar_t *workspace;
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 77d5752dc8..fbe5a035fd 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1268,7 +1268,18 @@ lookup_collation_cache(Oid collation, bool set_flags)
elog(ERROR, "cache lookup failed for collation %u", collation);
collform = (Form_pg_collation) GETSTRUCT(tp);
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ Datum datum;
+ const char *colllocale;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ colllocale = TextDatumGetCString(datum);
+
+ cache_entry->collate_is_c = true;
+ cache_entry->ctype_is_c = (strcmp(colllocale, "C") == 0);
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
Datum datum;
const char *collcollate;
@@ -1319,16 +1330,30 @@ lc_collate_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_COLLATE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_COLLATE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ result = true;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1372,16 +1397,29 @@ lc_ctype_is_c(Oid collation)
if (collation == DEFAULT_COLLATION_OID)
{
static int result = -1;
- char *localeptr;
-
- if (default_locale.provider == COLLPROVIDER_ICU)
- return false;
+ const char *localeptr;
if (result >= 0)
return (bool) result;
- localeptr = setlocale(LC_CTYPE, NULL);
- if (!localeptr)
- elog(ERROR, "invalid LC_CTYPE setting");
+
+ if (default_locale.provider == COLLPROVIDER_BUILTIN)
+ {
+ localeptr = default_locale.info.builtin.locale;
+ }
+ else if (default_locale.provider == COLLPROVIDER_ICU)
+ {
+ result = false;
+ return (bool) result;
+ }
+ else if (default_locale.provider == COLLPROVIDER_LIBC)
+ {
+ localeptr = setlocale(LC_CTYPE, NULL);
+ if (!localeptr)
+ elog(ERROR, "invalid LC_CTYPE setting");
+ }
+ else
+ elog(ERROR, "unexpected collation provider '%c'",
+ default_locale.provider);
if (strcmp(localeptr, "C") == 0)
result = true;
@@ -1519,10 +1557,10 @@ pg_newlocale_from_collation(Oid collid)
if (collid == DEFAULT_COLLATION_OID)
{
- if (default_locale.provider == COLLPROVIDER_ICU)
- return &default_locale;
- else
+ if (default_locale.provider == COLLPROVIDER_LIBC)
return (pg_locale_t) 0;
+ else
+ return &default_locale;
}
cache_entry = lookup_collation_cache(collid, false);
@@ -1547,7 +1585,20 @@ pg_newlocale_from_collation(Oid collid)
result.provider = collform->collprovider;
result.deterministic = collform->collisdeterministic;
- if (collform->collprovider == COLLPROVIDER_LIBC)
+ if (collform->collprovider == COLLPROVIDER_BUILTIN)
+ {
+ const char *locstr;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ locstr = TextDatumGetCString(datum);
+
+ if (strcmp(locstr, "C") != 0)
+ elog(ERROR, "unexpected builtin locale: %s", locstr);
+
+ result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
+ locstr);
+ }
+ else if (collform->collprovider == COLLPROVIDER_LIBC)
{
const char *collcollate;
const char *collctype pg_attribute_unused();
@@ -1626,6 +1677,7 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
+ Assert(collform->collprovider != COLLPROVIDER_BUILTIN);
datum = SysCacheGetAttrNotNull(COLLOID, tp, collform->collprovider == COLLPROVIDER_ICU ? Anum_pg_collation_colllocale : Anum_pg_collation_collcollate);
actual_versionstr = get_collation_actual_version(collform->collprovider,
@@ -1677,6 +1729,10 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
+ /* the builtin collation provider is not versioned */
+ if (collprovider == COLLPROVIDER_BUILTIN)
+ return NULL;
+
#ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU)
{
@@ -2443,6 +2499,31 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
return result;
}
+const char *
+builtin_validate_locale(int encoding, const char *locale)
+{
+ const char *canonical_name = NULL;
+ int required_encoding = -1;
+
+ if (strcmp(locale, "C") == 0)
+ canonical_name = "C";
+
+ if (!canonical_name)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ locale)));
+
+ if (required_encoding >= 0 && encoding != required_encoding)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("encoding \"%s\" does not match locale \"%s\"",
+ pg_encoding_to_char(encoding), locale)));
+
+ return canonical_name;
+}
+
+
#ifdef USE_ICU
/*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 2875bc97d3..0805398e24 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -423,7 +423,17 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
strcmp(ctype, "POSIX") == 0)
database_ctype_is_c = true;
- if (dbform->datlocprovider == COLLPROVIDER_ICU)
+ if (dbform->datlocprovider == COLLPROVIDER_BUILTIN)
+ {
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale);
+ datlocale = TextDatumGetCString(datum);
+
+ builtin_validate_locale(dbform->encoding, datlocale);
+
+ default_locale.info.builtin.locale = MemoryContextStrdup(
+ TopMemoryContext, datlocale);
+ }
+ else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
char *icurules;
@@ -461,10 +471,16 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
{
char *actual_versionstr;
char *collversionstr;
+ char *locale;
collversionstr = TextDatumGetCString(datum);
- actual_versionstr = get_collation_actual_version(dbform->datlocprovider, dbform->datlocprovider == COLLPROVIDER_ICU ? datlocale : collate);
+ if (dbform->datlocprovider == COLLPROVIDER_LIBC)
+ locale = collate;
+ else
+ locale = datlocale;
+
+ actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
if (!actual_versionstr)
/* should not happen */
elog(WARNING,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index de58002a5d..a26073f7c7 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -146,6 +146,7 @@ static char *lc_time = NULL;
static char *lc_messages = NULL;
static char locale_provider = COLLPROVIDER_LIBC;
static char *datlocale = NULL;
+static bool icu_locale_specified = false;
static char *icu_rules = NULL;
static const char *default_text_search_config = NULL;
static char *username = NULL;
@@ -2368,7 +2369,7 @@ setlocales(void)
lc_monetary = locale;
if (!lc_messages)
lc_messages = locale;
- if (!datlocale && locale_provider == COLLPROVIDER_ICU)
+ if (!datlocale && locale_provider != COLLPROVIDER_LIBC)
datlocale = locale;
}
@@ -2395,14 +2396,14 @@ setlocales(void)
lc_messages = canonname;
#endif
+ if (locale_provider != COLLPROVIDER_LIBC && datlocale == NULL)
+ pg_fatal("locale must be specified if provider is %s",
+ collprovider_name(locale_provider));
+
if (locale_provider == COLLPROVIDER_ICU)
{
char *langtag;
- /* acquire default locale from the environment, if not specified */
- if (datlocale == NULL)
- pg_fatal("ICU locale must be specified");
-
/* canonicalize to a language tag */
langtag = icu_language_tag(datlocale);
printf(_("Using language tag \"%s\" for ICU locale \"%s\".\n"),
@@ -2447,7 +2448,8 @@ usage(const char *progname)
" set default locale in the respective category for\n"
" new databases (default taken from environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --builtin-locale=LOCALE set builtin locale name for new databases\n"));
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" set default locale provider for new databases\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
printf(_(" -T, --text-search-config=CFG\n"
@@ -2609,9 +2611,9 @@ setup_locale_encoding(void)
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
- printf(_(" provider: %s\n"), collprovider_name(locale_provider));
- if (datlocale)
- printf(_(" ICU locale: %s\n"), datlocale);
+ printf(_(" default collation provider: %s\n"), collprovider_name(locale_provider));
+ if (locale_provider != COLLPROVIDER_LIBC)
+ printf(_(" default collation locale: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
@@ -3104,9 +3106,10 @@ main(int argc, char *argv[])
{"allow-group-access", no_argument, NULL, 'g'},
{"discard-caches", no_argument, NULL, 14},
{"locale-provider", required_argument, NULL, 15},
- {"icu-locale", required_argument, NULL, 16},
- {"icu-rules", required_argument, NULL, 17},
- {"sync-method", required_argument, NULL, 18},
+ {"builtin-locale", required_argument, NULL, 16},
+ {"icu-locale", required_argument, NULL, 17},
+ {"icu-rules", required_argument, NULL, 18},
+ {"sync-method", required_argument, NULL, 19},
{NULL, 0, NULL, 0}
};
@@ -3274,7 +3277,9 @@ main(int argc, char *argv[])
"-c debug_discard_caches=1");
break;
case 15:
- if (strcmp(optarg, "icu") == 0)
+ if (strcmp(optarg, "builtin") == 0)
+ locale_provider = COLLPROVIDER_BUILTIN;
+ else if (strcmp(optarg, "icu") == 0)
locale_provider = COLLPROVIDER_ICU;
else if (strcmp(optarg, "libc") == 0)
locale_provider = COLLPROVIDER_LIBC;
@@ -3285,9 +3290,13 @@ main(int argc, char *argv[])
datlocale = pg_strdup(optarg);
break;
case 17:
- icu_rules = pg_strdup(optarg);
+ datlocale = pg_strdup(optarg);
+ icu_locale_specified = true;
break;
case 18:
+ icu_rules = pg_strdup(optarg);
+ break;
+ case 19:
if (!parse_sync_method(optarg, &sync_method))
exit(1);
break;
@@ -3317,7 +3326,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (datlocale && locale_provider != COLLPROVIDER_ICU)
+ if (icu_locale_specified && locale_provider != COLLPROVIDER_ICU)
pg_fatal("%s cannot be specified unless locale provider \"%s\" is chosen",
"--icu-locale", "icu");
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 594b20cc74..e719f70dae 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -117,7 +117,7 @@ if ($ENV{with_icu} eq 'yes')
{
command_fails_like(
[ 'initdb', '--no-sync', '--locale-provider=icu', "$tempdir/data2" ],
- qr/initdb: error: ICU locale must be specified/,
+ qr/initdb: error: locale must be specified if provider is icu/,
'locale provider ICU requires --icu-locale');
command_ok(
@@ -138,7 +138,7 @@ if ($ENV{with_icu} eq 'yes')
'--lc-monetary=C', '--lc-time=C',
"$tempdir/data4"
],
- qr/^\s+ICU locale:\s+und\n/ms,
+ qr/^\s+default collation locale:\s+und\n/ms,
'options --locale-provider=icu --locale=und --lc-*=C');
command_fails_like(
@@ -184,6 +184,42 @@ else
'locale provider ICU fails since no ICU support');
}
+command_fails(
+ [ 'initdb', '--no-sync', '--locale-provider=builtin', "$tempdir/data6" ],
+ 'locale provider builtin fails without --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--locale=C',
+ "$tempdir/data7"
+ ],
+ 'locale provider builtin with --locale');
+
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--lc-ctype=C',
+ '--locale=C', "$tempdir/data10"
+ ],
+ 'locale provider builtin with --lc-ctype');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-locale=en',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU locale');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '--icu-rules=""',
+ "$tempdir/dataX"
+ ],
+ 'fails for locale provider builtin with ICU rules');
+
command_fails(
[ 'initdb', '--no-sync', '--locale-provider=xyz', "$tempdir/dataX" ],
'fails for invalid locale provider');
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 23e6217b73..0e4e7565ae 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3114,7 +3114,9 @@ dumpDatabase(Archive *fout)
}
appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
- if (datlocprovider[0] == 'c')
+ if (datlocprovider[0] == 'b')
+ appendPQExpBufferStr(creaQry, "builtin");
+ else if (datlocprovider[0] == 'c')
appendPQExpBufferStr(creaQry, "libc");
else if (datlocprovider[0] == 'i')
appendPQExpBufferStr(creaQry, "icu");
@@ -3122,27 +3124,33 @@ dumpDatabase(Archive *fout)
pg_fatal("unrecognized locale provider: %s",
datlocprovider);
- if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ if (!locale && datlocprovider[0] != 'c')
+ pg_log_warning("database '%s' with provider '%s' missing datlocale",
+ datname, datlocprovider);
+
+ if (locale && datlocprovider[0] == 'c')
+ pg_log_warning("database '%s' with provider 'c' has non-NULL locale '%s'",
+ datname, locale);
+
+ /* if collate and ctype are equal, and locale is NULL, use LOCALE */
+ if (!locale && strlen(collate) > 0 && strcmp(collate, ctype) == 0)
+ locale = collate;
+
+ /* output LC_COLLATE and LC_CTYPE if different from LOCALE */
+ if (strlen(collate) > 0 && (!locale || strcmp(collate, locale) != 0))
{
- appendPQExpBufferStr(creaQry, " LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
appendStringLiteralAH(creaQry, collate, fout);
}
- else
+ if (strlen(ctype) > 0 && (!locale || strcmp(ctype, locale) != 0))
{
- if (strlen(collate) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
- appendStringLiteralAH(creaQry, collate, fout);
- }
- if (strlen(ctype) > 0)
- {
- appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
- appendStringLiteralAH(creaQry, ctype, fout);
- }
+ appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+ appendStringLiteralAH(creaQry, ctype, fout);
}
+
if (locale)
{
- appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
+ appendPQExpBufferStr(creaQry, " LOCALE = ");
appendStringLiteralAH(creaQry, locale, fout);
}
@@ -13870,7 +13878,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
fmtQualifiedDumpable(collinfo));
appendPQExpBufferStr(q, "provider = ");
- if (collprovider[0] == 'c')
+ if (collprovider[0] == 'b')
+ appendPQExpBufferStr(q, "builtin");
+ else if (collprovider[0] == 'c')
appendPQExpBufferStr(q, "libc");
else if (collprovider[0] == 'i')
appendPQExpBufferStr(q, "icu");
@@ -13891,6 +13901,13 @@ dumpCollation(Archive *fout, const CollInfo *collinfo)
/* no locale -- the default collation cannot be reloaded anyway */
}
+ else if (collprovider[0] == 'b')
+ {
+ if (collcollate || collctype || colllocale || collicurules)
+ pg_log_warning("invalid collation \"%s\"", qcollname);
+
+ appendPQExpBufferStr(q, ", locale = 'C'");
+ }
else if (collprovider[0] == 'i')
{
if (fout->remoteVersion >= 150000)
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index 34a459496e..ed79c0930b 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -104,19 +104,13 @@ if ($oldnode->pg_version >= 11)
push @custom_opts, '--allow-group-access';
}
-# Set up the locale settings for the original cluster, so that we
-# can test that pg_upgrade copies the locale settings of template0
-# from the old to the new cluster.
+my $old_provider_field;
+my $old_datlocale_field;
-my $original_encoding = "6"; # UTF-8
-my $original_provider = "c";
-my $original_locale = "C";
-my $original_datlocale = "";
-my $provider_field = "'c' AS datlocprovider";
-my $old_datlocale_field = "NULL AS datlocale";
-if ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
+# account for field additions and changes
+if ($oldnode->pg_version >= 15)
{
- $provider_field = "datlocprovider";
+ $old_provider_field = "datlocprovider";
if ($oldnode->pg_version >= '17devel')
{
$old_datlocale_field = "datlocale";
@@ -125,18 +119,65 @@ if ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
{
$old_datlocale_field = "daticulocale AS datlocale";
}
+}
+else
+{
+ $old_provider_field = "'c' AS datlocprovider";
+ $old_datlocale_field = "NULL AS datlocale";
+}
+
+# Set up the locale settings for the original cluster, so that we
+# can test that pg_upgrade copies the locale settings of template0
+# from the old to the new cluster.
+
+my $original_enc_name;
+my $original_provider;
+my $original_datcollate = "C";
+my $original_datctype = "C";
+my $original_datlocale;
+
+if ($oldnode->pg_version >= '17devel')
+{
+ $original_enc_name = "UTF-8";
+ $original_provider = "b";
+ $original_datlocale = "C";
+}
+elsif ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
+{
+ $original_enc_name = "UTF-8";
$original_provider = "i";
$original_datlocale = "fr-CA";
}
+else
+{
+ $original_enc_name = "SQL_ASCII";
+ $original_provider = "c";
+ $original_datlocale = "";
+}
+
+my %encodings = ('UTF-8' => 6, 'SQL_ASCII' => 0);
+my $original_encoding = $encodings{$original_enc_name};
my @initdb_params = @custom_opts;
-push @initdb_params, ('--encoding', 'UTF-8');
-push @initdb_params, ('--locale', $original_locale);
-if ($original_provider eq "i")
+push @initdb_params, ('--encoding', $original_enc_name);
+push @initdb_params, ('--lc-collate', $original_datcollate);
+push @initdb_params, ('--lc-ctype', $original_datctype);
+
+# add --locale-provider, if supported
+my %provider_name = ('b' => 'builtin', 'i' => 'icu', 'c' => 'libc');
+if ($oldnode->pg_version >= 15)
{
- push @initdb_params, ('--locale-provider', 'icu');
- push @initdb_params, ('--icu-locale', 'fr-CA');
+ push @initdb_params,
+ ('--locale-provider', $provider_name{$original_provider});
+ if ($original_provider eq 'b')
+ {
+ push @initdb_params, ('--builtin-locale', $original_datlocale);
+ }
+ elsif ($original_provider eq 'i')
+ {
+ push @initdb_params, ('--icu-locale', $original_datlocale);
+ }
}
$node_params{extra} = \@initdb_params;
@@ -146,10 +187,10 @@ $oldnode->start;
my $result;
$result = $oldnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, $old_datlocale_field
+ "SELECT encoding, $old_provider_field, datcollate, datctype, $old_datlocale_field
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$original_encoding|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check locales in original cluster");
# The default location of the source code is the root of this directory.
@@ -433,10 +474,10 @@ if (-d $log_path)
# Test that upgraded cluster has original locale settings.
$result = $newnode->safe_psql(
'postgres',
- "SELECT encoding, $provider_field, datcollate, datctype, datlocale
+ "SELECT encoding, datlocprovider, datcollate, datctype, datlocale
FROM pg_database WHERE datname='template0'");
is( $result,
- "$original_encoding|$original_provider|$original_locale|$original_locale|$original_datlocale",
+ "$original_encoding|$original_provider|$original_datcollate|$original_datctype|$original_datlocale",
"check that locales in new cluster match original cluster");
# Second dump from the upgraded instance.
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 68b2ea8872..1ab80eb7ca 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -926,7 +926,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Encoding"));
if (pset.sversion >= 150000)
appendPQExpBuffer(&buf,
- " CASE d.datlocprovider WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE d.datlocprovider WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Locale Provider"));
else
appendPQExpBuffer(&buf,
@@ -4974,7 +4974,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
if (pset.sversion >= 100000)
appendPQExpBuffer(&buf,
- " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
+ " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
gettext_noop("Provider"));
else
appendPQExpBuffer(&buf,
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
index 14970a6a5f..4af4b98181 100644
--- a/src/bin/scripts/createdb.c
+++ b/src/bin/scripts/createdb.c
@@ -40,8 +40,9 @@ main(int argc, char *argv[])
{"locale", required_argument, NULL, 'l'},
{"maintenance-db", required_argument, NULL, 3},
{"locale-provider", required_argument, NULL, 4},
- {"icu-locale", required_argument, NULL, 5},
- {"icu-rules", required_argument, NULL, 6},
+ {"builtin-locale", required_argument, NULL, 5},
+ {"icu-locale", required_argument, NULL, 6},
+ {"icu-rules", required_argument, NULL, 7},
{NULL, 0, NULL, 0}
};
@@ -67,6 +68,7 @@ main(int argc, char *argv[])
char *lc_ctype = NULL;
char *locale = NULL;
char *locale_provider = NULL;
+ char *builtin_locale = NULL;
char *icu_locale = NULL;
char *icu_rules = NULL;
@@ -134,9 +136,12 @@ main(int argc, char *argv[])
locale_provider = pg_strdup(optarg);
break;
case 5:
- icu_locale = pg_strdup(optarg);
+ builtin_locale = pg_strdup(optarg);
break;
case 6:
+ icu_locale = pg_strdup(optarg);
+ break;
+ case 7:
icu_rules = pg_strdup(optarg);
break;
default:
@@ -216,6 +221,11 @@ main(int argc, char *argv[])
appendPQExpBufferStr(&sql, " LOCALE ");
appendStringLiteralConn(&sql, locale, conn);
}
+ if (builtin_locale)
+ {
+ appendPQExpBufferStr(&sql, " BUILTIN_LOCALE ");
+ appendStringLiteralConn(&sql, builtin_locale, conn);
+ }
if (lc_collate)
{
appendPQExpBufferStr(&sql, " LC_COLLATE ");
@@ -296,7 +306,7 @@ help(const char *progname)
printf(_(" --lc-ctype=LOCALE LC_CTYPE setting for the database\n"));
printf(_(" --icu-locale=LOCALE ICU locale setting for the database\n"));
printf(_(" --icu-rules=RULES ICU rules setting for the database\n"));
- printf(_(" --locale-provider={libc|icu}\n"
+ printf(_(" --locale-provider={builtin|libc|icu}\n"
" locale provider for the database's default collation\n"));
printf(_(" -O, --owner=OWNER database user to own the new database\n"));
printf(_(" -S, --strategy=STRATEGY database creation strategy wal_log or file_copy\n"));
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index 37e47b0078..dfd635bfab 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -105,6 +105,66 @@ else
'create database with ICU fails since no ICU support');
}
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ 'tbuiltin1'
+ ],
+ 'create database with provider "builtin" fails without --locale');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin2'
+ ],
+ 'create database with provider "builtin" and locale "C"');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-collate=C',
+ 'tbuiltin3'
+ ],
+ 'create database with provider "builtin" and LC_COLLATE=C');
+
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--lc-ctype=C',
+ 'tbuiltin4'
+ ],
+ 'create database with provider "builtin" and LC_CTYPE=C');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-locale=en',
+ 'tbuiltin7'
+ ],
+ 'create database with provider "builtin" and ICU_LOCALE="en"');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '--locale=C', '--icu-rules=""',
+ 'tbuiltin8'
+ ],
+ 'create database with provider "builtin" and ICU_RULES=""');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template1', '--locale-provider=builtin',
+ '--locale=C', 'tbuiltin9'
+ ],
+ 'create database with provider "builtin" not matching template');
+
$node->command_fails([ 'createdb', 'foobar1' ],
'fails if database already exists');
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 7396ff10c4..938432e8a4 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -23,9 +23,9 @@
descr => 'standard POSIX collation',
collname => 'POSIX', collprovider => 'c', collencoding => '-1',
collcollate => 'POSIX', collctype => 'POSIX' },
-{ oid => '962', descr => 'sorts by Unicode code point',
- collname => 'ucs_basic', collprovider => 'c', collencoding => '6',
- collcollate => 'C', collctype => 'C' },
+{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',
+ collname => 'ucs_basic', collprovider => 'b', collencoding => '6',
+ colllocale => 'C' },
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index a3e196fb53..5ce289d74b 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -68,6 +68,7 @@ MAKE_SYSCACHE(COLLOID, pg_collation_oid_index, 8);
#ifdef EXPOSE_TO_CLIENT_CODE
#define COLLPROVIDER_DEFAULT 'd'
+#define COLLPROVIDER_BUILTIN 'b'
#define COLLPROVIDER_ICU 'i'
#define COLLPROVIDER_LIBC 'c'
@@ -76,6 +77,8 @@ collprovider_name(char c)
{
switch (c)
{
+ case COLLPROVIDER_BUILTIN:
+ return "builtin";
case COLLPROVIDER_ICU:
return "icu";
case COLLPROVIDER_LIBC:
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 28c925b5af..2fd0c5157b 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -76,6 +76,10 @@ struct pg_locale_struct
bool deterministic;
union
{
+ struct
+ {
+ const char *locale;
+ } builtin;
locale_t lt;
#ifdef USE_ICU
struct
@@ -112,7 +116,7 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
pg_locale_t locale);
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
size_t srclen, pg_locale_t locale);
-
+extern const char *builtin_validate_locale(int encoding, const char *loc_str);
extern void icu_validate_locale(const char *loc_str);
extern char *icu_language_tag(const char *loc_str, int elevel);
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
index 8a1fc12ec6..5f8ef16803 100644
--- a/src/test/icu/t/010_database.pl
+++ b/src/test/icu/t/010_database.pl
@@ -27,9 +27,8 @@ CREATE TABLE icu (def text, en text COLLATE "en-x-icu", upfirst text COLLATE upp
INSERT INTO icu VALUES ('a', 'a', 'a'), ('b', 'b', 'b'), ('A', 'A', 'A'), ('B', 'B', 'B');
});
-is( $node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
- qq(t),
- 'ICU unicode version defined');
+is($node1->safe_psql('dbicu', q{SELECT icu_unicode_version() IS NOT NULL}),
+ qq(t), 'ICU unicode version defined');
is( $node1->safe_psql('dbicu', q{SELECT def FROM icu ORDER BY def}),
qq(A
@@ -63,14 +62,13 @@ is( $node1->psql(
0,
"C locale works for ICU");
-# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
-# are specified
-is( $node1->psql(
- 'postgres',
- q{CREATE DATABASE dbicu2 LOCALE_PROVIDER icu LOCALE '@colStrength=primary'
- LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0 ENCODING UTF8}
- ),
- 0,
- "LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE are specified");
+my ($ret, $stdout, $stderr) = $node1->psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
+);
+isnt($ret, 0, "locale provider must match template: exit code not 0");
+like(
+ $stderr,
+ qr/ERROR: new locale provider \(builtin\) does not match locale provider of the template database \(icu\)/,
+ "locale provider must match template: error message");
done_testing();
diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out
index 0649564485..593a622637 100644
--- a/src/test/regress/expected/collate.out
+++ b/src/test/regress/expected/collate.out
@@ -650,6 +650,22 @@ EXPLAIN (COSTS OFF)
(3 rows)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+ b
+-----
+ ABD
+ Abc
+ abc
+ bbc
+(4 rows)
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+ERROR: parameter "locale" must be specified
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+ERROR: invalid locale name "en_US" for builtin provider
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+ERROR: parameter "locale" must be specified
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
@@ -754,7 +770,7 @@ DETAIL: FROM cannot be specified together with any other options.
-- must get rid of them.
--
DROP SCHEMA collate_tests CASCADE;
-NOTICE: drop cascades to 19 other objects
+NOTICE: drop cascades to 20 other objects
DETAIL: drop cascades to table collate_test1
drop cascades to table collate_test_like
drop cascades to table collate_test2
@@ -771,6 +787,7 @@ drop cascades to function dup(anyelement)
drop cascades to table collate_test20
drop cascades to table collate_test21
drop cascades to table collate_test22
+drop cascades to collation builtin_c
drop cascades to collation mycoll2
drop cascades to table collate_test23
drop cascades to view collate_on_int
diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql
index c3d40fc195..4b0e4472c3 100644
--- a/src/test/regress/sql/collate.sql
+++ b/src/test/regress/sql/collate.sql
@@ -244,6 +244,14 @@ EXPLAIN (COSTS OFF)
-- CREATE/DROP COLLATION
+CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" );
+
+SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c;
+
+CREATE COLLATION builtin2 ( PROVIDER = builtin ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); -- fails
+CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); -- fails
+
CREATE COLLATION mycoll1 FROM "C";
CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" );
CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported
--
2.34.1
[text/x-patch] v23-0002-Add-C.UTF-8-locale-to-the-new-builtin-collation-.patch (27.3K, ../../[email protected]/3-v23-0002-Add-C.UTF-8-locale-to-the-new-builtin-collation-.patch)
download | inline diff:
From bf68d8f296e0318aada97cb527453af0d2616f34 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 17:41:51 -0800
Subject: [PATCH v23 2/6] Add C.UTF-8 locale to the new builtin collation
provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
----- CATVERSION -----
The builtin C.UTF-8 locale has similar semantics to the libc locale of
the same name. That is, code point sort order (fast, memcmp-based)
combined with Unicode semantics for character operations such as
pattern matching, regular expressions, and
LOWER()/INITCAP()/UPPER(). The character semantics are based on
Unicode simple case mappings.
The builtin provider's C.UTF-8 offers several important advantages
over libc:
* faster sorting -- benefits from additional optimizations such as
abbreviated keys and varstrfastcmp_c
* faster case conversion, e.g. LOWER(), at least compared with some
libc implementations
* available on all platforms with identical semantics, and the
semantics are stable, testable, and documentable within a given
Postgres major version
Being based on memcmp, the builtin C.UTF-8 locale does not offer
natural language sort order. But it is an improvement for most use
cases that might otherwise use libc's "C.UTF-8" locale, as well as
many use cases that use libc's "C" locale.
Discussion: https://postgr.es/m/ff4c2f2f9c8fc7ca27c1c24ae37ecaeaeaff6b53.camel%40j-davis.com
Reviewed-by: Daniel Vérité, Peter Eisentraut, Jeremy Schneider
---
doc/src/sgml/charset.sgml | 27 +++-
doc/src/sgml/ref/create_collation.sgml | 2 +-
doc/src/sgml/ref/create_database.sgml | 3 +-
doc/src/sgml/ref/initdb.sgml | 2 +-
src/backend/regex/regc_pg_locale.c | 36 ++++-
src/backend/utils/adt/formatting.c | 123 +++++++++++++++++
src/backend/utils/adt/pg_locale.c | 15 +-
src/bin/initdb/t/001_initdb.pl | 17 +++
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 2 +-
src/bin/scripts/t/020_createdb.pl | 18 +++
src/include/catalog/pg_collation.dat | 3 +
src/test/regress/expected/collate.utf8.out | 136 +++++++++++++++++++
src/test/regress/expected/collate.utf8_1.out | 8 ++
src/test/regress/parallel_schedule | 4 +-
src/test/regress/sql/collate.utf8.sql | 67 +++++++++
15 files changed, 453 insertions(+), 10 deletions(-)
create mode 100644 src/test/regress/expected/collate.utf8.out
create mode 100644 src/test/regress/expected/collate.utf8_1.out
create mode 100644 src/test/regress/sql/collate.utf8.sql
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 7114eb7b52..55bbb20dac 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -377,13 +377,21 @@ initdb --locale-provider=icu --icu-locale=en
<listitem>
<para>
The <literal>builtin</literal> provider uses built-in operations. Only
- the <literal>C</literal> locale is supported for this provider.
+ the <literal>C</literal> and <literal>C.UTF-8</literal> locales are
+ supported for this provider.
</para>
<para>
The <literal>C</literal> locale behavior is identical to the
<literal>C</literal> locale in the libc provider. When using this
locale, the behavior may depend on the database encoding.
</para>
+ <para>
+ The <literal>C.UTF-8</literal> locale is available only for when the
+ database encoding is <literal>UTF-8</literal>, and the behavior is
+ based on Unicode. The collation uses the code point values only. The
+ regular expression character classes are based on the "POSIX
+ Compatible" semantics, and the case mapping is the "simple" variant.
+ </para>
</listitem>
</varlistentry>
@@ -878,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_c_utf8</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function>, it uses
+ Unicode simple case mapping. For pattern matching (including regular
+ expressions), it uses the POSIX Compatible variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. This collation is
+ only available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
<listitem>
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 98cd7d56be..85f18cbbe5 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -99,7 +99,7 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<para>
If <replaceable>provider</replaceable> is <literal>builtin</literal>,
then <replaceable>locale</replaceable> must be specified and set to
- <literal>C</literal>.
+ either <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 6c1fd95602..1f5cdf1271 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -165,7 +165,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<para>
If <xref linkend="create-database-locale-provider"/> is
<literal>builtin</literal>, then <replaceable>locale</replaceable>
- must be specified and set to <literal>C</literal>.
+ must be specified and set to either <literal>C</literal> or
+ <literal>C.UTF-8</literal>.
</para>
<tip>
<para>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index 4760570f6a..08a1c2538f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -289,7 +289,7 @@ PostgreSQL documentation
<para>
If <option>--locale-provider</option> is <literal>builtin</literal>,
<option>--locale</option> must be specified and set to
- <literal>C</literal>.
+ <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 6a26388bfa..85f3238eb0 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -16,6 +16,8 @@
*/
#include "catalog/pg_collation.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "utils/pg_locale.h"
/*
@@ -64,6 +66,7 @@
typedef enum
{
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
+ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
@@ -266,7 +269,12 @@ pg_set_regex_collation(Oid collation)
if (GetDatabaseEncoding() == PG_UTF8)
{
if (pg_regex_locale)
- pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ {
+ if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ pg_regex_strategy = PG_REGEX_BUILTIN;
+ else
+ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
@@ -290,6 +298,8 @@ pg_wc_isdigit(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isdigit(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -322,6 +332,8 @@ pg_wc_isalpha(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALPHA));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
@@ -354,6 +366,8 @@ pg_wc_isalnum(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalnum(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -395,6 +409,8 @@ pg_wc_isupper(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISUPPER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
@@ -427,6 +443,8 @@ pg_wc_islower(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISLOWER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
@@ -459,6 +477,8 @@ pg_wc_isgraph(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISGRAPH));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
@@ -491,6 +511,8 @@ pg_wc_isprint(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPRINT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
@@ -523,6 +545,8 @@ pg_wc_ispunct(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_ispunct(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
@@ -555,6 +579,8 @@ pg_wc_isspace(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISSPACE));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
@@ -588,6 +614,8 @@ pg_wc_toupper(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_uppercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -628,6 +656,8 @@ pg_wc_tolower(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_lowercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -792,6 +822,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
#endif
break;
+ case PG_REGEX_BUILTIN:
+ max_chr = (pg_wchar) MAX_SIMPLE_CHR;
+ break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
@@ -809,6 +842,7 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break;
default:
+ Assert(false);
max_chr = 0; /* can't get here, but keep compiler quiet */
break;
}
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 5f483b8dbc..1a578b8a2b 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -77,6 +77,8 @@
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "mb/pg_wchar.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
@@ -1679,6 +1681,33 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1799,6 +1828,33 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1920,6 +1976,73 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const unsigned char *src = (unsigned char *) buff;
+ unsigned char *dst;
+ size_t dstsize = nbytes + 1;
+ int srcoff = 0;
+ int dstoff = 0;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* Output workspace cannot have more codes than input bytes */
+ dst = (unsigned char *) palloc(dstsize);
+
+ while (srcoff < nbytes)
+ {
+ pg_wchar u1 = utf8_to_unicode(src + srcoff);
+ pg_wchar u2;
+ int u1len = unicode_utf8len(u1);
+ int u2len;
+
+ if (wasalnum)
+ u2 = unicode_lowercase_simple(u1);
+ else
+ u2 = unicode_uppercase_simple(u1);
+
+ u2len = unicode_utf8len(u2);
+
+ wasalnum = pg_u_isalnum(u2, true);
+
+ /*
+ * If we can't fit the necessary bytes and a terminating NUL,
+ * reallocate buffer to the maximum size we might need, and
+ * shrink it later.
+ */
+ if (dstoff + u2len + 1 > dstsize)
+ {
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ dstsize = (nbytes + 1) * sizeof(pg_wchar);
+ dst = repalloc(dst, dstsize);
+ }
+
+ unicode_to_utf8(u2, dst + dstoff);
+ srcoff += u1len;
+ dstoff += u2len;
+ }
+
+ *(dst + dstoff) = '\0';
+ dstoff++;
+
+ if (dstsize == dstoff)
+ {
+ result = (char *) dst;
+ }
+ else
+ {
+ /* shrink buffer and store result */
+ result = palloc(dstoff);
+ memcpy(result, dst, dstoff);
+ pfree(dst);
+ }
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index fbe5a035fd..d5d22957af 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1592,7 +1592,7 @@ pg_newlocale_from_collation(Oid collid)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
locstr = TextDatumGetCString(datum);
- if (strcmp(locstr, "C") != 0)
+ if (strcmp(locstr, "C.UTF-8") != 0 && strcmp(locstr, "C") != 0)
elog(ERROR, "unexpected builtin locale: %s", locstr);
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
@@ -1729,7 +1729,11 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
- /* the builtin collation provider is not versioned */
+ /*
+ * The only two supported locales (C and C.UTF-8) are both based on memcmp
+ * and do not change. (The ctype behavior can change, but the versioning
+ * does not track that.)
+ */
if (collprovider == COLLPROVIDER_BUILTIN)
return NULL;
@@ -2506,7 +2510,14 @@ builtin_validate_locale(int encoding, const char *locale)
int required_encoding = -1;
if (strcmp(locale, "C") == 0)
+ {
canonical_name = "C";
+ }
+ else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "C.UTF-8";
+ }
if (!canonical_name)
ereport(ERROR,
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index e719f70dae..c5408b6f2d 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -196,6 +196,23 @@ command_ok(
],
'locale provider builtin with --locale');
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E SQL_ASCII',
+ '--builtin-locale=C.UTF-8', "$tempdir/data9"
+ ],
+ 'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
+);
+
command_ok(
[
'initdb', '--no-sync',
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index ed79c0930b..3e67121a8d 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -140,7 +140,7 @@ if ($oldnode->pg_version >= '17devel')
{
$original_enc_name = "UTF-8";
$original_provider = "b";
- $original_datlocale = "C";
+ $original_datlocale = "C.UTF-8";
}
elsif ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
{
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index dfd635bfab..3ba623f9d1 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -139,6 +139,24 @@ $node->command_ok(
],
'create database with provider "builtin" and LC_CTYPE=C');
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E UTF-8', '--builtin-locale=C.UTF8',
+ 'tbuiltin5'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E LATIN1', '--builtin-locale=C.UTF-8',
+ 'tbuiltin6'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
$node->command_fails(
[
'createdb', '-T',
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 938432e8a4..b95a89491d 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -30,5 +30,8 @@
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
+{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
+ collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
+ colllocale => 'C.UTF-8' },
]
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
new file mode 100644
index 0000000000..eff0ef21ac
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8.out
@@ -0,0 +1,136 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+SET client_encoding TO UTF8;
+--
+-- Test PG_C_UTF8
+--
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C_UTF8'); -- fails
+ERROR: invalid locale name "C_UTF8" for builtin provider
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF8');
+DROP COLLATION regress_pg_c_utf8;
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF-8');
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+-----------------+-----------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs ßss Déf | ÁBC SßS ßSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | DŽxxdž DŽxxdž DŽxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_c_utf8;
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+ lower
+-------
+ ασ
+(1 row)
+
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+ lower
+-------
+ αͺσͺ
+(1 row)
+
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+ lower
+-------
+ α΄σ΄
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/expected/collate.utf8_1.out b/src/test/regress/expected/collate.utf8_1.out
new file mode 100644
index 0000000000..e73fdf50c3
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8_1.out
@@ -0,0 +1,8 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 1d8a414eea..e48cb4b7a3 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,9 +78,9 @@ test: brin_bloom brin_multi
# psql depends on create_am
# amutils depends on geometry, create_index_spgist, hash_index, brin
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps
-# collate.*.utf8 tests cannot be run in parallel with each other
+# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252
# ----------
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
new file mode 100644
index 0000000000..1f5f9ef491
--- /dev/null
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -0,0 +1,67 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+SET client_encoding TO UTF8;
+
+--
+-- Test PG_C_UTF8
+--
+
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C_UTF8'); -- fails
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF8');
+DROP COLLATION regress_pg_c_utf8;
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF-8');
+
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+
+DROP TABLE test_pg_c_utf8;
+
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
--
2.34.1
[text/x-patch] v23-0003-Inline-basic-UTF-8-functions.patch (4.4K, ../../[email protected]/4-v23-0003-Inline-basic-UTF-8-functions.patch)
download | inline diff:
From 4ecb46c1f4816a3a5ee26c10fc9fd8a32b03885a Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 2 Mar 2024 11:27:23 -0800
Subject: [PATCH v23 3/6] Inline basic UTF-8 functions.
Shows a measurable speedup when processing UTF-8 data, such as with
the new builtin collation provider.
Discussion: https://postgr.es/m/[email protected]
---
src/common/wchar.c | 61 ---------------------------------------
src/include/mb/pg_wchar.h | 61 +++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 61 deletions(-)
diff --git a/src/common/wchar.c b/src/common/wchar.c
index a238c0106c..76b7dfdfcb 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -476,39 +476,6 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
}
-/*
- * Map a Unicode code point to UTF-8. utf8string must have at least
- * unicode_utf8len(c) bytes available.
- */
-unsigned char *
-unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
-{
- if (c <= 0x7F)
- {
- utf8string[0] = c;
- }
- else if (c <= 0x7FF)
- {
- utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
- utf8string[1] = 0x80 | (c & 0x3F);
- }
- else if (c <= 0xFFFF)
- {
- utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
- utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[2] = 0x80 | (c & 0x3F);
- }
- else
- {
- utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
- utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
- utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[3] = 0x80 | (c & 0x3F);
- }
-
- return utf8string;
-}
-
/*
* Trivial conversion from pg_wchar to UTF-8.
* caller should allocate enough space for "to"
@@ -670,34 +637,6 @@ ucs_wcwidth(pg_wchar ucs)
return 1;
}
-/*
- * Convert a UTF-8 character to a Unicode code point.
- * This is a one-character version of pg_utf2wchar_with_len.
- *
- * No error checks here, c must point to a long-enough string.
- */
-pg_wchar
-utf8_to_unicode(const unsigned char *c)
-{
- if ((*c & 0x80) == 0)
- return (pg_wchar) c[0];
- else if ((*c & 0xe0) == 0xc0)
- return (pg_wchar) (((c[0] & 0x1f) << 6) |
- (c[1] & 0x3f));
- else if ((*c & 0xf0) == 0xe0)
- return (pg_wchar) (((c[0] & 0x0f) << 12) |
- ((c[1] & 0x3f) << 6) |
- (c[2] & 0x3f));
- else if ((*c & 0xf8) == 0xf0)
- return (pg_wchar) (((c[0] & 0x07) << 18) |
- ((c[1] & 0x3f) << 12) |
- ((c[2] & 0x3f) << 6) |
- (c[3] & 0x3f));
- else
- /* that is an invalid code on purpose */
- return 0xffffffff;
-}
-
static int
pg_utf_dsplen(const unsigned char *s)
{
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 69a55b66f4..249cd18a35 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -555,6 +555,67 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Convert a UTF-8 character to a Unicode code point.
+ * This is a one-character version of pg_utf2wchar_with_len.
+ *
+ * No error checks here, c must point to a long-enough string.
+ */
+static inline pg_wchar
+utf8_to_unicode(const unsigned char *c)
+{
+ if ((*c & 0x80) == 0)
+ return (pg_wchar) c[0];
+ else if ((*c & 0xe0) == 0xc0)
+ return (pg_wchar) (((c[0] & 0x1f) << 6) |
+ (c[1] & 0x3f));
+ else if ((*c & 0xf0) == 0xe0)
+ return (pg_wchar) (((c[0] & 0x0f) << 12) |
+ ((c[1] & 0x3f) << 6) |
+ (c[2] & 0x3f));
+ else if ((*c & 0xf8) == 0xf0)
+ return (pg_wchar) (((c[0] & 0x07) << 18) |
+ ((c[1] & 0x3f) << 12) |
+ ((c[2] & 0x3f) << 6) |
+ (c[3] & 0x3f));
+ else
+ /* that is an invalid code on purpose */
+ return 0xffffffff;
+}
+
+/*
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
+ */
+static inline unsigned char *
+unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
+{
+ if (c <= 0x7F)
+ {
+ utf8string[0] = c;
+ }
+ else if (c <= 0x7FF)
+ {
+ utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
+ utf8string[1] = 0x80 | (c & 0x3F);
+ }
+ else if (c <= 0xFFFF)
+ {
+ utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
+ utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[2] = 0x80 | (c & 0x3F);
+ }
+ else
+ {
+ utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
+ utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
+ utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[3] = 0x80 | (c & 0x3F);
+ }
+
+ return utf8string;
+}
+
/*
* Number of bytes needed to represent the given char in UTF8.
*/
--
2.34.1
[text/x-patch] v23-0004-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch (9.4K, ../../[email protected]/5-v23-0004-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch)
download | inline diff:
From ffa57f4a6b2b01ae1ba0154cace7ae843f643342 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 7 Mar 2024 12:26:02 -0800
Subject: [PATCH v23 4/6] Add unicode_strtitle() for Unicode Default Case
Conversion.
This brings the titlecasing implementation out of formatting.c and
into unicode_case.c by accepting an arbitrary word boundary callback.
Simple for now, but can be extended to support the Unicode Default
Case Conversion algorithm with full case mapping.
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 124 ++++++++++++++++-------------
src/common/unicode_case.c | 76 ++++++++++++++++--
src/include/common/unicode_case.h | 5 ++
3 files changed, 142 insertions(+), 63 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 1a578b8a2b..6d5cbe2929 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1920,6 +1920,47 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
return result;
}
+struct WordBoundaryState
+{
+ const char *str;
+ size_t len;
+ size_t offset;
+ bool init;
+ bool prev_alnum;
+};
+
+/*
+ * Simple word boundary iterator that draws boundaries each time the result of
+ * pg_u_isalnum() changes.
+ */
+static size_t
+initcap_wbnext(void *state)
+{
+ struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
+
+ while (wbstate->offset < wbstate->len &&
+ wbstate->str[wbstate->offset] != '\0')
+ {
+ pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ wbstate->offset);
+ bool curr_alnum = pg_u_isalnum(u, true);
+
+ if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
+ {
+ size_t prev_offset = wbstate->offset;
+
+ wbstate->init = true;
+ wbstate->offset += unicode_utf8len(u);
+ wbstate->prev_alnum = curr_alnum;
+ return prev_offset;
+ }
+
+ wbstate->offset += unicode_utf8len(u);
+ }
+
+ return wbstate->len;
+}
+
/*
* collation-aware, wide-character-aware initcap function
*
@@ -1978,69 +2019,42 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
#endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
{
- const unsigned char *src = (unsigned char *) buff;
- unsigned char *dst;
- size_t dstsize = nbytes + 1;
- int srcoff = 0;
- int dstoff = 0;
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+ struct WordBoundaryState wbstate = {
+ .str = src,
+ .len = srclen,
+ .offset = 0,
+ .init = false,
+ .prev_alnum = false,
+ };
Assert(GetDatabaseEncoding() == PG_UTF8);
- /* Output workspace cannot have more codes than input bytes */
- dst = (unsigned char *) palloc(dstsize);
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
- while (srcoff < nbytes)
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ if (needed + 1 > dstsize)
{
- pg_wchar u1 = utf8_to_unicode(src + srcoff);
- pg_wchar u2;
- int u1len = unicode_utf8len(u1);
- int u2len;
-
- if (wasalnum)
- u2 = unicode_lowercase_simple(u1);
- else
- u2 = unicode_uppercase_simple(u1);
-
- u2len = unicode_utf8len(u2);
-
- wasalnum = pg_u_isalnum(u2, true);
-
- /*
- * If we can't fit the necessary bytes and a terminating NUL,
- * reallocate buffer to the maximum size we might need, and
- * shrink it later.
- */
- if (dstoff + u2len + 1 > dstsize)
- {
- /* Overflow paranoia */
- if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
-
- dstsize = (nbytes + 1) * sizeof(pg_wchar);
- dst = repalloc(dst, dstsize);
- }
+ /* reset iterator */
+ wbstate.offset = 0;
+ wbstate.prev_alnum = false;
- unicode_to_utf8(u2, dst + dstoff);
- srcoff += u1len;
- dstoff += u2len;
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ Assert(needed + 1 == dstsize);
}
- *(dst + dstoff) = '\0';
- dstoff++;
-
- if (dstsize == dstoff)
- {
- result = (char *) dst;
- }
- else
- {
- /* shrink buffer and store result */
- result = palloc(dstoff);
- memcpy(result, dst, dstoff);
- pfree(dst);
- }
+ result = dst;
}
else
{
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 8b77f39e4d..7eb9e89f3f 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -21,8 +21,9 @@
#include "mb/pg_wchar.h"
static const pg_case_map *find_case_map(pg_wchar ucs);
-static size_t convert_case(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, CaseKind casekind);
+static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ CaseKind str_casekind, WordBoundaryNext wbnext,
+ void *wbstate);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -67,7 +68,40 @@ unicode_uppercase_simple(pg_wchar code)
size_t
unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+}
+
+/*
+ * unicode_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * Titlecasing requires knowledge about word boundaries, which is provided by
+ * the callback wbnext. A word boundary is the offset of the start of a word
+ * or the offset of the character immediately following a word.
+ *
+ * The caller is expected to initialize and free the callback state
+ * wbstate. The callback should first return offset 0 for the first boundary;
+ * then the offset of each subsequent word boundary; then the total length of
+ * the string to indicate the final boundary.
+ */
+size_t
+unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ WordBoundaryNext wbnext, void *wbstate)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ wbstate);
}
/*
@@ -89,20 +123,34 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
size_t
unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
}
/*
- * Implement Unicode Default Case Conversion algorithm.
+ * If str_casekind is CaseLower or CaseUpper, map each character in the string
+ * for which a mapping is available.
*
- * Map each character in the string for which a mapping is available.
+ * If str_casekind is CaseTitle, maps characters found on a word boundary to
+ * uppercase and other characters to lowercase.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind casekind)
+ CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
{
+ /* character CaseKind varies while titlecasing */
+ CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
+ size_t boundary = 0;
+
+ Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
+ (str_casekind != CaseTitle && !wbnext && !wbstate));
+
+ if (str_casekind == CaseTitle)
+ {
+ boundary = wbnext(wbstate);
+ Assert(boundary == 0); /* start of text is always a boundary */
+ }
while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
{
@@ -110,9 +158,21 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
int u1len = unicode_utf8len(u1);
const pg_case_map *casemap = find_case_map(u1);
+ if (str_casekind == CaseTitle)
+ {
+ if (srcoff == boundary)
+ {
+ chr_casekind = CaseUpper;
+ boundary = wbnext(wbstate);
+ }
+ else
+ chr_casekind = CaseLower;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
if (casemap)
{
- pg_wchar u2 = casemap->simplemap[casekind];
+ pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
if (result_len + u2len < dstsize)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index df36d8db21..c0c3382e79 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -16,11 +16,16 @@
#include "mb/pg_wchar.h"
+typedef size_t (*WordBoundaryNext) (void *wbstate);
+
pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
+size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
+ ssize_t srclen, WordBoundaryNext wbnext,
+ void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
--
2.34.1
[text/x-patch] v23-0005-Support-Unicode-full-case-mapping-and-conversion.patch (555.7K, ../../[email protected]/6-v23-0005-Support-Unicode-full-case-mapping-and-conversion.patch)
download | inline diff:
From 6b12f2770be288e314b9957bb03e711a148b6fb1 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 9 Mar 2024 12:55:21 -0800
Subject: [PATCH v23 5/6] Support Unicode full case mapping and conversion.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Generate tables from Unicode SpecialCasing.txt to support more
sophisticated case mapping behavior:
* support case mappings to multiple codepoints, such as "ß"
uppercasing to "SS"
* support conditional case mappings, such as the "final sigma"
* support titlecase variants, such as "dž" uppercasing to "DŽ" but
titlecasing to "Dž"
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 12 +-
src/common/unicode/Makefile | 4 +-
.../unicode/generate-unicode_case_table.pl | 161 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_case.c | 185 +-
src/include/common/unicode_case.h | 8 +-
src/include/common/unicode_case_table.h | 6094 +++++++++--------
7 files changed, 3481 insertions(+), 2987 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 6d5cbe2929..97ccf23583 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,13 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1842,13 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -2038,7 +2038,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2049,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index c38ab36b1e..87d7355794 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -30,7 +30,7 @@ update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
@@ -91,4 +91,4 @@ clean:
rm -f $(OBJS) case_test case_test.o category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
index 44b785b861..02da4b682f 100644
--- a/src/common/unicode/generate-unicode_case_table.pl
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -3,7 +3,7 @@
# Generate Unicode character case mappings. Does not include tailoring
# or locale-specific mappings.
#
-# Input: UnicodeData.txt
+# Input: SpecialCasing.txt UnicodeData.txt
# Output: unicode_case_table.h
#
# Copyright (c) 2000-2023, PostgreSQL Global Development Group
@@ -21,6 +21,10 @@ GetOptions('outdir:s' => \$output_path);
my $output_table_file = "$output_path/unicode_case_table.h";
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
my $FH;
my %simple = ();
@@ -51,6 +55,98 @@ while (my $line = <$FH>)
}
close $FH;
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
# Start writing out the output files
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
@@ -63,6 +159,8 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
$num_simple++ unless $code < 0x80;
}
+my $num_special = scalar(keys %special) + 1;
+
print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
@@ -86,6 +184,19 @@ print $OT <<"EOS";
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -94,12 +205,47 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
@@ -114,8 +260,10 @@ for (my $code = 0; $code < 0x80; $code++)
my $lc = ($simple{$code}{Simple_Lowercase} || $code);
my $tc = ($simple{$code}{Simple_Titlecase} || $code);
my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
$code, $lc, $tc, $uc;
}
printf $OT "\n";
@@ -126,9 +274,14 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
next unless $code >= 0x80; # already output above
my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
$code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
- $map->{Simple_Uppercase};
+ $map->{Simple_Uppercase}, $special_case;
}
print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index b9a4181c32..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_case_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
output: ['unicode_case_table.h'],
command: [
perl, files('generate-unicode_case_table.pl'),
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 7eb9e89f3f..ce14c8061d 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -22,8 +22,10 @@
static const pg_case_map *find_case_map(pg_wchar ucs);
static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext,
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -64,11 +66,16 @@ unicode_uppercase_simple(pg_wchar code)
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, full, NULL,
+ NULL);
}
/*
@@ -87,6 +94,13 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
*
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied; use titlecase mapping for the first character;
+ * and perform adjustment to the first Cased character after a word
+ * boundary. If full is false, use only simple mappings; use uppercase mapping
+ * for the first character; and map the first character of each word to
+ * uppercase.
+ *
* Titlecasing requires knowledge about word boundaries, which is provided by
* the callback wbnext. A word boundary is the offset of the start of a word
* or the offset of the character immediately following a word.
@@ -98,9 +112,9 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
*/
size_t
unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- WordBoundaryNext wbnext, void *wbstate)
+ bool full, WordBoundaryNext wbnext, void *wbstate)
{
- return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, full, wbnext,
wbstate);
}
@@ -119,29 +133,42 @@ unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, full, NULL,
+ NULL);
}
/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
* If str_casekind is CaseLower or CaseUpper, map each character in the string
* for which a mapping is available.
*
- * If str_casekind is CaseTitle, maps characters found on a word boundary to
- * uppercase and other characters to lowercase.
+ * If str_casekind is CaseTitle: for each word boundary, "adjust" forward to
+ * the next Cased character and map it to titlecase; then map subsequent
+ * characters to lowercase until the next word boundary.
+ *
+ * Some characters have special mappings, which can map a single codepoint to
+ * multiple codepoints, or depend on conditions.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
+ void *wbstate)
{
/* character CaseKind varies while titlecasing */
CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
size_t boundary = 0;
+ bool adjusting = true;
Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
(str_casekind != CaseTitle && !wbnext && !wbstate));
@@ -156,21 +183,77 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
{
pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
- const pg_case_map *casemap = find_case_map(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+ /*
+ * Titlecasing has two states: adjusting from boundary (initial
+ * state), and lowercasing until the next boundary.
+ */
if (str_casekind == CaseTitle)
{
if (srcoff == boundary)
{
- chr_casekind = CaseUpper;
+ /* reset to initial state and find the next boundary */
+ adjusting = true;
boundary = wbnext(wbstate);
}
+
+ if (adjusting)
+ {
+ if (!full || pg_u_prop_cased(u1))
+ {
+ /* adjustment done: map to titlecase */
+ adjusting = false;
+ chr_casekind = full ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else
+ casemap = NULL; /* no mapping during adjustment */
+ }
else
+ {
chr_casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Note: only a single special mapping per codepoint is currently
+ * supported, though Unicode allows for multiple special mappings for
+ * a single codepoint.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
}
/* perform mapping, update result_len, and write to dst */
- if (casemap)
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[chr_casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
{
pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
@@ -198,6 +281,82 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
return result_len;
}
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
/* find entry in simple case map, if any */
static const pg_case_map *
find_case_map(pg_wchar ucs)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index c0c3382e79..c982815823 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -22,11 +22,11 @@ pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, WordBoundaryNext wbnext,
- void *wbstate);
+ ssize_t srclen, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
index b239f0b3c3..081d4133b1 100644
--- a/src/include/common/unicode_case_table.h
+++ b/src/include/common/unicode_case_table.h
@@ -20,6 +20,19 @@
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -28,2974 +41,3143 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
*/
-static const pg_case_map case_map[2955] =
+static const pg_case_map case_map[3003] =
{
/* begin dense entries for codepoints < 0x80 */
- {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}},
- {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}},
- {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}},
- {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}},
- {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}},
- {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}},
- {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}},
- {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}},
- {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}},
- {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}},
- {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}},
- {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}},
- {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}},
- {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}},
- {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}},
- {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}},
- {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}},
- {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}},
- {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}},
- {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}},
- {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}},
- {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}},
- {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}},
- {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}},
- {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}},
- {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}},
- {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}},
- {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}},
- {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}},
- {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}},
- {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}},
- {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}},
- {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}},
- {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}},
- {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}},
- {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}},
- {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}},
- {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}},
- {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}},
- {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}},
- {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}},
- {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}},
- {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}},
- {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}},
- {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}},
- {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}},
- {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}},
- {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}},
- {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}},
- {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}},
- {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}},
- {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}},
- {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}},
- {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}},
- {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}},
- {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}},
- {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}},
- {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}},
- {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}},
- {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}},
- {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}},
- {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}},
- {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}},
- {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}},
- {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}},
- {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}},
- {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}},
- {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}},
- {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}},
- {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}},
- {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}},
- {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}},
- {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}},
- {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}},
- {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}},
- {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}},
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
/* begin sparse entries for codepoints >= 0x80 */
- {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}},
- {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}},
- {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}},
- {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}},
- {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}},
- {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}},
- {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}},
- {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}},
- {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}},
- {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}},
- {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}},
- {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}},
- {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}},
- {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}},
- {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}},
- {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}},
- {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}},
- {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}},
- {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}},
- {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}},
- {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}},
- {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}},
- {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}},
- {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}},
- {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}},
- {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}},
- {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}},
- {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}},
- {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}},
- {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}},
- {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}},
- {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}},
- {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}},
- {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}},
- {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}},
- {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}},
- {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}},
- {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}},
- {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}},
- {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}},
- {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}},
- {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}},
- {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}},
- {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}},
- {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}},
- {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}},
- {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}},
- {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}},
- {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}},
- {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}},
- {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}},
- {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}},
- {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}},
- {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}},
- {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}},
- {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}},
- {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}},
- {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}},
- {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}},
- {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}},
- {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}},
- {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}},
- {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}},
- {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}},
- {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}},
- {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}},
- {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}},
- {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}},
- {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}},
- {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}},
- {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}},
- {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}},
- {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}},
- {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}},
- {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}},
- {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}},
- {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}},
- {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}},
- {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}},
- {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}},
- {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}},
- {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}},
- {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}},
- {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}},
- {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}},
- {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}},
- {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}},
- {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}},
- {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}},
- {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}},
- {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}},
- {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}},
- {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}},
- {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}},
- {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}},
- {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}},
- {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}},
- {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}},
- {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
- {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
};
--
2.34.1
[text/x-patch] v23-0006-Add-PG_UNICODE_FAST-locale-to-the-builtin-collat.patch (16.7K, ../../[email protected]/7-v23-0006-Add-PG_UNICODE_FAST-locale-to-the-builtin-collat.patch)
download | inline diff:
From a8c12e49db6a7cf7b9cb477c2a3cbca6f6f77405 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 18:15:33 -0800
Subject: [PATCH v23 6/6] Add PG_UNICODE_FAST locale to the builtin collation
provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The PG_UNICODE_FAST locale uses code point sort order (fast,
memcmp-based) combined with Unicode character semantics. The character
semantics are based on Unicode full case mapping.
Full case mapping can map a single codepoint to multiple codepoints,
such as "ß" uppercasing to "SS". Additionally, it handles
context-sensitive mappings like the "final sigma", and it uses
titlecase mappings such as "Dž" when titlecasing (rather than plain
uppercase mappings).
Importantly, the uppercasing of "ß" as "SS" is specifically mentioned
by the SQL standard. In Postgres, UCS_BASIC uses plain ASCII semantics
for case mapping and pattern matching, so if we changed it to use the
PG_UNICODE_FAST locale, it would offer better compliance with the
standard. For now, though, do not change the behavior of UCS_BASIC.
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 17 +++
src/backend/regex/regc_pg_locale.c | 11 +-
src/backend/utils/adt/formatting.c | 22 ++-
src/backend/utils/adt/pg_locale.c | 16 ++-
src/include/catalog/pg_collation.dat | 3 +
src/include/utils/pg_locale.h | 1 +
src/test/regress/expected/collate.utf8.out | 160 +++++++++++++++++++++
src/test/regress/sql/collate.utf8.sql | 60 ++++++++
8 files changed, 279 insertions(+), 11 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 55bbb20dac..fc520138a6 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -886,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_unicode_fast</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. It is only
+ available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>pg_c_utf8</literal></term>
<listitem>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 85f3238eb0..24c5200cef 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -78,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -271,7 +273,10 @@ pg_set_regex_collation(Oid collation)
if (pg_regex_locale)
{
if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = !pg_regex_locale->info.builtin.casemap_full;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
}
@@ -299,7 +304,7 @@ pg_wc_isdigit(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
case PG_REGEX_BUILTIN:
- return pg_u_isdigit(c, true);
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -367,7 +372,7 @@ pg_wc_isalnum(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
case PG_REGEX_BUILTIN:
- return pg_u_isalnum(c, true);
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -546,7 +551,7 @@ pg_wc_ispunct(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
case PG_REGEX_BUILTIN:
- return pg_u_ispunct(c, true);
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 97ccf23583..47601e75ba 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,15 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1844,15 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1927,6 +1931,7 @@ struct WordBoundaryState
size_t offset;
bool init;
bool prev_alnum;
+ bool posix;
};
/*
@@ -1943,7 +1948,7 @@ initcap_wbnext(void *state)
{
pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
- bool curr_alnum = pg_u_isalnum(u, true);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
{
@@ -2030,6 +2035,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
.offset = 0,
.init = false,
.prev_alnum = false,
+ .posix = !mylocale->info.builtin.casemap_full,
};
Assert(GetDatabaseEncoding() == PG_UTF8);
@@ -2038,7 +2044,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2056,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index d5d22957af..6079fd01d8 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1592,7 +1592,16 @@ pg_newlocale_from_collation(Oid collid)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
locstr = TextDatumGetCString(datum);
- if (strcmp(locstr, "C.UTF-8") != 0 && strcmp(locstr, "C") != 0)
+ if (strcmp(locstr, "PG_UNICODE_FAST") == 0)
+ {
+ result.info.builtin.casemap_full = true;
+ }
+ else if (strcmp(locstr, "C") == 0 ||
+ strcmp(locstr, "C.UTF-8") == 0)
+ {
+ result.info.builtin.casemap_full = false;
+ }
+ else
elog(ERROR, "unexpected builtin locale: %s", locstr);
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
@@ -2518,6 +2527,11 @@ builtin_validate_locale(int encoding, const char *locale)
required_encoding = PG_UTF8;
canonical_name = "C.UTF-8";
}
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "PG_UNICODE_FAST";
+ }
if (!canonical_name)
ereport(ERROR,
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index b95a89491d..a187b3dcef 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -33,5 +33,8 @@
{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
colllocale => 'C.UTF-8' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST' },
]
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 2fd0c5157b..b5b1ed45e8 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -79,6 +79,7 @@ struct pg_locale_struct
struct
{
const char *locale;
+ bool casemap_full;
} builtin;
locale_t lt;
#ifdef USE_ICU
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index eff0ef21ac..63327a8fdd 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -134,3 +134,163 @@ SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
t
(1 row)
+--
+-- Test PG_UNICODE_FAST
+--
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+ERROR: invalid locale name "unicode" for builtin provider
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123Abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_unicode_fast;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index 1f5f9ef491..c63928d38e 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -65,3 +65,63 @@ SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+
+--
+-- Test PG_UNICODE_FAST
+--
+
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+
+DROP TABLE test_pg_unicode_fast;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-14 08:08 ` Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 14:38 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
0 siblings, 2 replies; 94+ messages in thread
From: Jeff Davis @ 2024-03-14 08:08 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Wed, 2024-03-13 at 00:44 -0700, Jeff Davis wrote:
> New series attached. I plan to commit 0001 very soon.
Committed the basic builtin provider, supporting only the "C" locale.
There were a few changes since the last version I posted:
* Added simplistic validation of the locale name to initdb.c (missing
before).
* Consistently passed the locale name to
get_collation_actual_version(). In the previous patch, the caller
sometimes just passed NULL knowing that the builtin provider is not
versioned, but that's not the caller's responsibility.
* pg_dump previously had some minor refactoring, which you had some
questions about. I eliminated that and just kept it to the changes
necessary for the builtin provider.
* createdb --help was missing the --builtin-locale option
* improved error checking order in createdb() to avoid a confusing
error message.
I also attached a rebased series.
0001 (the C.UTF-8 locale) is also close. Considering that most of the
infrastructure is already in place, that's not a large patch. You many
have some comments about the way I'm canonicalizing and validating in
initdb -- that could be cleaner, but it feels like I should refactor
the surrounding code separately first.
0002 (inlining utf8 functions) is also ready.
For 0003 and beyond, I'd like some validation that it's what you had in
mind.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v24-0001-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch (28.0K, ../../[email protected]/2-v24-0001-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch)
download | inline diff:
From 6c6b7c6128e84f4053badbf777f4f57039f0e92a Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 17:41:51 -0800
Subject: [PATCH v24 1/5] Support C.UTF-8 locale in the new builtin collation
provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
----- CATVERSION -----
The builtin C.UTF-8 locale has similar semantics to the libc locale of
the same name. That is, code point sort order (fast, memcmp-based)
combined with Unicode semantics for character operations such as
pattern matching, regular expressions, and
LOWER()/INITCAP()/UPPER(). The character semantics are based on
Unicode simple case mappings.
The builtin provider's C.UTF-8 offers several important advantages
over libc:
* faster sorting -- benefits from additional optimizations such as
abbreviated keys and varstrfastcmp_c
* faster case conversion, e.g. LOWER(), at least compared with some
libc implementations
* available on all platforms with identical semantics, and the
semantics are stable, testable, and documentable within a given
Postgres major version
Being based on memcmp, the builtin C.UTF-8 locale does not offer
natural language sort order. But it is an improvement for most use
cases that might otherwise use libc's "C.UTF-8" locale, as well as
many use cases that use libc's "C" locale.
Discussion: https://postgr.es/m/ff4c2f2f9c8fc7ca27c1c24ae37ecaeaeaff6b53.camel%40j-davis.com
Reviewed-by: Daniel Vérité, Peter Eisentraut, Jeremy Schneider
---
doc/src/sgml/charset.sgml | 27 +++-
doc/src/sgml/ref/create_collation.sgml | 2 +-
doc/src/sgml/ref/create_database.sgml | 3 +-
doc/src/sgml/ref/initdb.sgml | 2 +-
src/backend/regex/regc_pg_locale.c | 36 ++++-
src/backend/utils/adt/formatting.c | 123 +++++++++++++++++
src/backend/utils/adt/pg_locale.c | 13 +-
src/bin/initdb/initdb.c | 16 ++-
src/bin/initdb/t/001_initdb.pl | 17 +++
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 2 +-
src/bin/scripts/t/020_createdb.pl | 18 +++
src/include/catalog/pg_collation.dat | 3 +
src/test/regress/expected/collate.utf8.out | 136 +++++++++++++++++++
src/test/regress/expected/collate.utf8_1.out | 8 ++
src/test/regress/parallel_schedule | 4 +-
src/test/regress/sql/collate.utf8.sql | 67 +++++++++
16 files changed, 467 insertions(+), 10 deletions(-)
create mode 100644 src/test/regress/expected/collate.utf8.out
create mode 100644 src/test/regress/expected/collate.utf8_1.out
create mode 100644 src/test/regress/sql/collate.utf8.sql
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 7114eb7b52..55bbb20dac 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -377,13 +377,21 @@ initdb --locale-provider=icu --icu-locale=en
<listitem>
<para>
The <literal>builtin</literal> provider uses built-in operations. Only
- the <literal>C</literal> locale is supported for this provider.
+ the <literal>C</literal> and <literal>C.UTF-8</literal> locales are
+ supported for this provider.
</para>
<para>
The <literal>C</literal> locale behavior is identical to the
<literal>C</literal> locale in the libc provider. When using this
locale, the behavior may depend on the database encoding.
</para>
+ <para>
+ The <literal>C.UTF-8</literal> locale is available only for when the
+ database encoding is <literal>UTF-8</literal>, and the behavior is
+ based on Unicode. The collation uses the code point values only. The
+ regular expression character classes are based on the "POSIX
+ Compatible" semantics, and the case mapping is the "simple" variant.
+ </para>
</listitem>
</varlistentry>
@@ -878,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_c_utf8</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function>, it uses
+ Unicode simple case mapping. For pattern matching (including regular
+ expressions), it uses the POSIX Compatible variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. This collation is
+ only available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
<listitem>
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 98cd7d56be..85f18cbbe5 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -99,7 +99,7 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<para>
If <replaceable>provider</replaceable> is <literal>builtin</literal>,
then <replaceable>locale</replaceable> must be specified and set to
- <literal>C</literal>.
+ either <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 6c1fd95602..1f5cdf1271 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -165,7 +165,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<para>
If <xref linkend="create-database-locale-provider"/> is
<literal>builtin</literal>, then <replaceable>locale</replaceable>
- must be specified and set to <literal>C</literal>.
+ must be specified and set to either <literal>C</literal> or
+ <literal>C.UTF-8</literal>.
</para>
<tip>
<para>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index 4760570f6a..08a1c2538f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -289,7 +289,7 @@ PostgreSQL documentation
<para>
If <option>--locale-provider</option> is <literal>builtin</literal>,
<option>--locale</option> must be specified and set to
- <literal>C</literal>.
+ <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 6a26388bfa..85f3238eb0 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -16,6 +16,8 @@
*/
#include "catalog/pg_collation.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "utils/pg_locale.h"
/*
@@ -64,6 +66,7 @@
typedef enum
{
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
+ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
@@ -266,7 +269,12 @@ pg_set_regex_collation(Oid collation)
if (GetDatabaseEncoding() == PG_UTF8)
{
if (pg_regex_locale)
- pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ {
+ if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ pg_regex_strategy = PG_REGEX_BUILTIN;
+ else
+ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
@@ -290,6 +298,8 @@ pg_wc_isdigit(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isdigit(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -322,6 +332,8 @@ pg_wc_isalpha(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALPHA));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
@@ -354,6 +366,8 @@ pg_wc_isalnum(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalnum(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -395,6 +409,8 @@ pg_wc_isupper(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISUPPER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
@@ -427,6 +443,8 @@ pg_wc_islower(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISLOWER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
@@ -459,6 +477,8 @@ pg_wc_isgraph(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISGRAPH));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
@@ -491,6 +511,8 @@ pg_wc_isprint(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPRINT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
@@ -523,6 +545,8 @@ pg_wc_ispunct(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_ispunct(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
@@ -555,6 +579,8 @@ pg_wc_isspace(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISSPACE));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
@@ -588,6 +614,8 @@ pg_wc_toupper(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_uppercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -628,6 +656,8 @@ pg_wc_tolower(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_lowercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -792,6 +822,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
#endif
break;
+ case PG_REGEX_BUILTIN:
+ max_chr = (pg_wchar) MAX_SIMPLE_CHR;
+ break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
@@ -809,6 +842,7 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break;
default:
+ Assert(false);
max_chr = 0; /* can't get here, but keep compiler quiet */
break;
}
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 5f483b8dbc..1a578b8a2b 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -77,6 +77,8 @@
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "mb/pg_wchar.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
@@ -1679,6 +1681,33 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1799,6 +1828,33 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1920,6 +1976,73 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const unsigned char *src = (unsigned char *) buff;
+ unsigned char *dst;
+ size_t dstsize = nbytes + 1;
+ int srcoff = 0;
+ int dstoff = 0;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* Output workspace cannot have more codes than input bytes */
+ dst = (unsigned char *) palloc(dstsize);
+
+ while (srcoff < nbytes)
+ {
+ pg_wchar u1 = utf8_to_unicode(src + srcoff);
+ pg_wchar u2;
+ int u1len = unicode_utf8len(u1);
+ int u2len;
+
+ if (wasalnum)
+ u2 = unicode_lowercase_simple(u1);
+ else
+ u2 = unicode_uppercase_simple(u1);
+
+ u2len = unicode_utf8len(u2);
+
+ wasalnum = pg_u_isalnum(u2, true);
+
+ /*
+ * If we can't fit the necessary bytes and a terminating NUL,
+ * reallocate buffer to the maximum size we might need, and
+ * shrink it later.
+ */
+ if (dstoff + u2len + 1 > dstsize)
+ {
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ dstsize = (nbytes + 1) * sizeof(pg_wchar);
+ dst = repalloc(dst, dstsize);
+ }
+
+ unicode_to_utf8(u2, dst + dstoff);
+ srcoff += u1len;
+ dstoff += u2len;
+ }
+
+ *(dst + dstoff) = '\0';
+ dstoff++;
+
+ if (dstsize == dstoff)
+ {
+ result = (char *) dst;
+ }
+ else
+ {
+ /* shrink buffer and store result */
+ result = palloc(dstoff);
+ memcpy(result, dst, dstoff);
+ pfree(dst);
+ }
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 39390fbe4e..a5aeabce94 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1731,7 +1731,11 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
- /* the builtin collation provider is not versioned */
+ /*
+ * The only two supported locales (C and C.UTF-8) are both based on memcmp
+ * and do not change. (The ctype behavior can change, but the versioning
+ * does not track that.)
+ */
if (collprovider == COLLPROVIDER_BUILTIN)
return NULL;
@@ -2508,7 +2512,14 @@ builtin_validate_locale(int encoding, const char *locale)
int required_encoding = -1;
if (strcmp(locale, "C") == 0)
+ {
canonical_name = "C";
+ }
+ else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "C.UTF-8";
+ }
if (!canonical_name)
ereport(ERROR,
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 8d53ef4a1f..ac33508d32 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2403,9 +2403,16 @@ setlocales(void)
if (locale_provider == COLLPROVIDER_BUILTIN)
{
- if (strcmp(datlocale, "C") != 0)
+ if (strcmp(datlocale, "C") == 0)
+ canonname = "C";
+ else if (strcmp(datlocale, "C.UTF-8") == 0 ||
+ strcmp(datlocale, "C.UTF8") == 0)
+ canonname = "C.UTF-8";
+ else
pg_fatal("invalid locale name \"%s\" for builtin provider",
datlocale);
+
+ datlocale = canonname;
}
else if (locale_provider == COLLPROVIDER_ICU)
{
@@ -2694,6 +2701,13 @@ setup_locale_encoding(void)
!check_locale_encoding(lc_collate, encodingid))
exit(1); /* check_locale_encoding printed the error */
+ if (locale_provider == COLLPROVIDER_BUILTIN)
+ {
+ if (strcmp(datlocale, "C.UTF-8") == 0 && encodingid != PG_UTF8)
+ pg_fatal("builtin provider locale \"%s\" requires encoding \"%s\"",
+ datlocale, "UTF-8");
+ }
+
if (locale_provider == COLLPROVIDER_ICU &&
!check_icu_locale_encoding(encodingid))
exit(1);
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index e719f70dae..c5408b6f2d 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -196,6 +196,23 @@ command_ok(
],
'locale provider builtin with --locale');
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E SQL_ASCII',
+ '--builtin-locale=C.UTF-8', "$tempdir/data9"
+ ],
+ 'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
+);
+
command_ok(
[
'initdb', '--no-sync',
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index ed79c0930b..3e67121a8d 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -140,7 +140,7 @@ if ($oldnode->pg_version >= '17devel')
{
$original_enc_name = "UTF-8";
$original_provider = "b";
- $original_datlocale = "C";
+ $original_datlocale = "C.UTF-8";
}
elsif ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
{
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index dfd635bfab..3ba623f9d1 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -139,6 +139,24 @@ $node->command_ok(
],
'create database with provider "builtin" and LC_CTYPE=C');
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E UTF-8', '--builtin-locale=C.UTF8',
+ 'tbuiltin5'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E LATIN1', '--builtin-locale=C.UTF-8',
+ 'tbuiltin6'
+ ],
+ 'create database with provider "builtin" and --builtin-locale C.UTF-8');
+
$node->command_fails(
[
'createdb', '-T',
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 938432e8a4..b95a89491d 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -30,5 +30,8 @@
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
+{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
+ collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
+ colllocale => 'C.UTF-8' },
]
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
new file mode 100644
index 0000000000..eff0ef21ac
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8.out
@@ -0,0 +1,136 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+SET client_encoding TO UTF8;
+--
+-- Test PG_C_UTF8
+--
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C_UTF8'); -- fails
+ERROR: invalid locale name "C_UTF8" for builtin provider
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF8');
+DROP COLLATION regress_pg_c_utf8;
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF-8');
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+-----------------+-----------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs ßss Déf | ÁBC SßS ßSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | DŽxxdž DŽxxdž DŽxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_c_utf8;
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+ lower
+-------
+ ασ
+(1 row)
+
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+ lower
+-------
+ αͺσͺ
+(1 row)
+
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+ lower
+-------
+ α΄σ΄
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/expected/collate.utf8_1.out b/src/test/regress/expected/collate.utf8_1.out
new file mode 100644
index 0000000000..e73fdf50c3
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8_1.out
@@ -0,0 +1,8 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 1d8a414eea..e48cb4b7a3 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,9 +78,9 @@ test: brin_bloom brin_multi
# psql depends on create_am
# amutils depends on geometry, create_index_spgist, hash_index, brin
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps
-# collate.*.utf8 tests cannot be run in parallel with each other
+# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252
# ----------
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
new file mode 100644
index 0000000000..1f5f9ef491
--- /dev/null
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -0,0 +1,67 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+SET client_encoding TO UTF8;
+
+--
+-- Test PG_C_UTF8
+--
+
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C_UTF8'); -- fails
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF8');
+DROP COLLATION regress_pg_c_utf8;
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF-8');
+
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+
+DROP TABLE test_pg_c_utf8;
+
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
--
2.34.1
[text/x-patch] v24-0002-Inline-basic-UTF-8-functions.patch (4.4K, ../../[email protected]/3-v24-0002-Inline-basic-UTF-8-functions.patch)
download | inline diff:
From 359b295e47d2861cc391395ff27ec750f0fd4f6f Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 2 Mar 2024 11:27:23 -0800
Subject: [PATCH v24 2/5] Inline basic UTF-8 functions.
Shows a measurable speedup when processing UTF-8 data, such as with
the new builtin collation provider.
Discussion: https://postgr.es/m/[email protected]
---
src/common/wchar.c | 61 ---------------------------------------
src/include/mb/pg_wchar.h | 61 +++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 61 deletions(-)
diff --git a/src/common/wchar.c b/src/common/wchar.c
index a238c0106c..76b7dfdfcb 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -476,39 +476,6 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
}
-/*
- * Map a Unicode code point to UTF-8. utf8string must have at least
- * unicode_utf8len(c) bytes available.
- */
-unsigned char *
-unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
-{
- if (c <= 0x7F)
- {
- utf8string[0] = c;
- }
- else if (c <= 0x7FF)
- {
- utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
- utf8string[1] = 0x80 | (c & 0x3F);
- }
- else if (c <= 0xFFFF)
- {
- utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
- utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[2] = 0x80 | (c & 0x3F);
- }
- else
- {
- utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
- utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
- utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[3] = 0x80 | (c & 0x3F);
- }
-
- return utf8string;
-}
-
/*
* Trivial conversion from pg_wchar to UTF-8.
* caller should allocate enough space for "to"
@@ -670,34 +637,6 @@ ucs_wcwidth(pg_wchar ucs)
return 1;
}
-/*
- * Convert a UTF-8 character to a Unicode code point.
- * This is a one-character version of pg_utf2wchar_with_len.
- *
- * No error checks here, c must point to a long-enough string.
- */
-pg_wchar
-utf8_to_unicode(const unsigned char *c)
-{
- if ((*c & 0x80) == 0)
- return (pg_wchar) c[0];
- else if ((*c & 0xe0) == 0xc0)
- return (pg_wchar) (((c[0] & 0x1f) << 6) |
- (c[1] & 0x3f));
- else if ((*c & 0xf0) == 0xe0)
- return (pg_wchar) (((c[0] & 0x0f) << 12) |
- ((c[1] & 0x3f) << 6) |
- (c[2] & 0x3f));
- else if ((*c & 0xf8) == 0xf0)
- return (pg_wchar) (((c[0] & 0x07) << 18) |
- ((c[1] & 0x3f) << 12) |
- ((c[2] & 0x3f) << 6) |
- (c[3] & 0x3f));
- else
- /* that is an invalid code on purpose */
- return 0xffffffff;
-}
-
static int
pg_utf_dsplen(const unsigned char *s)
{
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 69a55b66f4..249cd18a35 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -555,6 +555,67 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Convert a UTF-8 character to a Unicode code point.
+ * This is a one-character version of pg_utf2wchar_with_len.
+ *
+ * No error checks here, c must point to a long-enough string.
+ */
+static inline pg_wchar
+utf8_to_unicode(const unsigned char *c)
+{
+ if ((*c & 0x80) == 0)
+ return (pg_wchar) c[0];
+ else if ((*c & 0xe0) == 0xc0)
+ return (pg_wchar) (((c[0] & 0x1f) << 6) |
+ (c[1] & 0x3f));
+ else if ((*c & 0xf0) == 0xe0)
+ return (pg_wchar) (((c[0] & 0x0f) << 12) |
+ ((c[1] & 0x3f) << 6) |
+ (c[2] & 0x3f));
+ else if ((*c & 0xf8) == 0xf0)
+ return (pg_wchar) (((c[0] & 0x07) << 18) |
+ ((c[1] & 0x3f) << 12) |
+ ((c[2] & 0x3f) << 6) |
+ (c[3] & 0x3f));
+ else
+ /* that is an invalid code on purpose */
+ return 0xffffffff;
+}
+
+/*
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
+ */
+static inline unsigned char *
+unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
+{
+ if (c <= 0x7F)
+ {
+ utf8string[0] = c;
+ }
+ else if (c <= 0x7FF)
+ {
+ utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
+ utf8string[1] = 0x80 | (c & 0x3F);
+ }
+ else if (c <= 0xFFFF)
+ {
+ utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
+ utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[2] = 0x80 | (c & 0x3F);
+ }
+ else
+ {
+ utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
+ utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
+ utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[3] = 0x80 | (c & 0x3F);
+ }
+
+ return utf8string;
+}
+
/*
* Number of bytes needed to represent the given char in UTF8.
*/
--
2.34.1
[text/x-patch] v24-0003-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch (9.4K, ../../[email protected]/4-v24-0003-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch)
download | inline diff:
From 28568e32bcac7b13e2ec4657884727272d185e50 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 7 Mar 2024 12:26:02 -0800
Subject: [PATCH v24 3/5] Add unicode_strtitle() for Unicode Default Case
Conversion.
This brings the titlecasing implementation out of formatting.c and
into unicode_case.c by accepting an arbitrary word boundary callback.
Simple for now, but can be extended to support the Unicode Default
Case Conversion algorithm with full case mapping.
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 124 ++++++++++++++++-------------
src/common/unicode_case.c | 76 ++++++++++++++++--
src/include/common/unicode_case.h | 5 ++
3 files changed, 142 insertions(+), 63 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 1a578b8a2b..6d5cbe2929 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1920,6 +1920,47 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
return result;
}
+struct WordBoundaryState
+{
+ const char *str;
+ size_t len;
+ size_t offset;
+ bool init;
+ bool prev_alnum;
+};
+
+/*
+ * Simple word boundary iterator that draws boundaries each time the result of
+ * pg_u_isalnum() changes.
+ */
+static size_t
+initcap_wbnext(void *state)
+{
+ struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
+
+ while (wbstate->offset < wbstate->len &&
+ wbstate->str[wbstate->offset] != '\0')
+ {
+ pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ wbstate->offset);
+ bool curr_alnum = pg_u_isalnum(u, true);
+
+ if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
+ {
+ size_t prev_offset = wbstate->offset;
+
+ wbstate->init = true;
+ wbstate->offset += unicode_utf8len(u);
+ wbstate->prev_alnum = curr_alnum;
+ return prev_offset;
+ }
+
+ wbstate->offset += unicode_utf8len(u);
+ }
+
+ return wbstate->len;
+}
+
/*
* collation-aware, wide-character-aware initcap function
*
@@ -1978,69 +2019,42 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
#endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
{
- const unsigned char *src = (unsigned char *) buff;
- unsigned char *dst;
- size_t dstsize = nbytes + 1;
- int srcoff = 0;
- int dstoff = 0;
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+ struct WordBoundaryState wbstate = {
+ .str = src,
+ .len = srclen,
+ .offset = 0,
+ .init = false,
+ .prev_alnum = false,
+ };
Assert(GetDatabaseEncoding() == PG_UTF8);
- /* Output workspace cannot have more codes than input bytes */
- dst = (unsigned char *) palloc(dstsize);
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
- while (srcoff < nbytes)
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ if (needed + 1 > dstsize)
{
- pg_wchar u1 = utf8_to_unicode(src + srcoff);
- pg_wchar u2;
- int u1len = unicode_utf8len(u1);
- int u2len;
-
- if (wasalnum)
- u2 = unicode_lowercase_simple(u1);
- else
- u2 = unicode_uppercase_simple(u1);
-
- u2len = unicode_utf8len(u2);
-
- wasalnum = pg_u_isalnum(u2, true);
-
- /*
- * If we can't fit the necessary bytes and a terminating NUL,
- * reallocate buffer to the maximum size we might need, and
- * shrink it later.
- */
- if (dstoff + u2len + 1 > dstsize)
- {
- /* Overflow paranoia */
- if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
-
- dstsize = (nbytes + 1) * sizeof(pg_wchar);
- dst = repalloc(dst, dstsize);
- }
+ /* reset iterator */
+ wbstate.offset = 0;
+ wbstate.prev_alnum = false;
- unicode_to_utf8(u2, dst + dstoff);
- srcoff += u1len;
- dstoff += u2len;
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ Assert(needed + 1 == dstsize);
}
- *(dst + dstoff) = '\0';
- dstoff++;
-
- if (dstsize == dstoff)
- {
- result = (char *) dst;
- }
- else
- {
- /* shrink buffer and store result */
- result = palloc(dstoff);
- memcpy(result, dst, dstoff);
- pfree(dst);
- }
+ result = dst;
}
else
{
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 8b77f39e4d..7eb9e89f3f 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -21,8 +21,9 @@
#include "mb/pg_wchar.h"
static const pg_case_map *find_case_map(pg_wchar ucs);
-static size_t convert_case(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, CaseKind casekind);
+static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ CaseKind str_casekind, WordBoundaryNext wbnext,
+ void *wbstate);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -67,7 +68,40 @@ unicode_uppercase_simple(pg_wchar code)
size_t
unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+}
+
+/*
+ * unicode_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * Titlecasing requires knowledge about word boundaries, which is provided by
+ * the callback wbnext. A word boundary is the offset of the start of a word
+ * or the offset of the character immediately following a word.
+ *
+ * The caller is expected to initialize and free the callback state
+ * wbstate. The callback should first return offset 0 for the first boundary;
+ * then the offset of each subsequent word boundary; then the total length of
+ * the string to indicate the final boundary.
+ */
+size_t
+unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ WordBoundaryNext wbnext, void *wbstate)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ wbstate);
}
/*
@@ -89,20 +123,34 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
size_t
unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
}
/*
- * Implement Unicode Default Case Conversion algorithm.
+ * If str_casekind is CaseLower or CaseUpper, map each character in the string
+ * for which a mapping is available.
*
- * Map each character in the string for which a mapping is available.
+ * If str_casekind is CaseTitle, maps characters found on a word boundary to
+ * uppercase and other characters to lowercase.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind casekind)
+ CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
{
+ /* character CaseKind varies while titlecasing */
+ CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
+ size_t boundary = 0;
+
+ Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
+ (str_casekind != CaseTitle && !wbnext && !wbstate));
+
+ if (str_casekind == CaseTitle)
+ {
+ boundary = wbnext(wbstate);
+ Assert(boundary == 0); /* start of text is always a boundary */
+ }
while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
{
@@ -110,9 +158,21 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
int u1len = unicode_utf8len(u1);
const pg_case_map *casemap = find_case_map(u1);
+ if (str_casekind == CaseTitle)
+ {
+ if (srcoff == boundary)
+ {
+ chr_casekind = CaseUpper;
+ boundary = wbnext(wbstate);
+ }
+ else
+ chr_casekind = CaseLower;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
if (casemap)
{
- pg_wchar u2 = casemap->simplemap[casekind];
+ pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
if (result_len + u2len < dstsize)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index df36d8db21..c0c3382e79 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -16,11 +16,16 @@
#include "mb/pg_wchar.h"
+typedef size_t (*WordBoundaryNext) (void *wbstate);
+
pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
+size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
+ ssize_t srclen, WordBoundaryNext wbnext,
+ void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
--
2.34.1
[text/x-patch] v24-0004-Support-Unicode-full-case-mapping-and-conversion.patch (555.7K, ../../[email protected]/5-v24-0004-Support-Unicode-full-case-mapping-and-conversion.patch)
download | inline diff:
From 14fe6921119d62e4c687479c8705beb8fd525fe0 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 9 Mar 2024 12:55:21 -0800
Subject: [PATCH v24 4/5] Support Unicode full case mapping and conversion.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Generate tables from Unicode SpecialCasing.txt to support more
sophisticated case mapping behavior:
* support case mappings to multiple codepoints, such as "ß"
uppercasing to "SS"
* support conditional case mappings, such as the "final sigma"
* support titlecase variants, such as "dž" uppercasing to "DŽ" but
titlecasing to "Dž"
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 12 +-
src/common/unicode/Makefile | 4 +-
.../unicode/generate-unicode_case_table.pl | 161 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_case.c | 185 +-
src/include/common/unicode_case.h | 8 +-
src/include/common/unicode_case_table.h | 6094 +++++++++--------
7 files changed, 3481 insertions(+), 2987 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 6d5cbe2929..97ccf23583 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,13 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1842,13 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -2038,7 +2038,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2049,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index c38ab36b1e..87d7355794 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -30,7 +30,7 @@ update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
@@ -91,4 +91,4 @@ clean:
rm -f $(OBJS) case_test case_test.o category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
index 44b785b861..02da4b682f 100644
--- a/src/common/unicode/generate-unicode_case_table.pl
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -3,7 +3,7 @@
# Generate Unicode character case mappings. Does not include tailoring
# or locale-specific mappings.
#
-# Input: UnicodeData.txt
+# Input: SpecialCasing.txt UnicodeData.txt
# Output: unicode_case_table.h
#
# Copyright (c) 2000-2023, PostgreSQL Global Development Group
@@ -21,6 +21,10 @@ GetOptions('outdir:s' => \$output_path);
my $output_table_file = "$output_path/unicode_case_table.h";
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
my $FH;
my %simple = ();
@@ -51,6 +55,98 @@ while (my $line = <$FH>)
}
close $FH;
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
# Start writing out the output files
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
@@ -63,6 +159,8 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
$num_simple++ unless $code < 0x80;
}
+my $num_special = scalar(keys %special) + 1;
+
print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
@@ -86,6 +184,19 @@ print $OT <<"EOS";
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -94,12 +205,47 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
@@ -114,8 +260,10 @@ for (my $code = 0; $code < 0x80; $code++)
my $lc = ($simple{$code}{Simple_Lowercase} || $code);
my $tc = ($simple{$code}{Simple_Titlecase} || $code);
my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
$code, $lc, $tc, $uc;
}
printf $OT "\n";
@@ -126,9 +274,14 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
next unless $code >= 0x80; # already output above
my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
$code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
- $map->{Simple_Uppercase};
+ $map->{Simple_Uppercase}, $special_case;
}
print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index b9a4181c32..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_case_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
output: ['unicode_case_table.h'],
command: [
perl, files('generate-unicode_case_table.pl'),
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 7eb9e89f3f..ce14c8061d 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -22,8 +22,10 @@
static const pg_case_map *find_case_map(pg_wchar ucs);
static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext,
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -64,11 +66,16 @@ unicode_uppercase_simple(pg_wchar code)
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, full, NULL,
+ NULL);
}
/*
@@ -87,6 +94,13 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
*
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied; use titlecase mapping for the first character;
+ * and perform adjustment to the first Cased character after a word
+ * boundary. If full is false, use only simple mappings; use uppercase mapping
+ * for the first character; and map the first character of each word to
+ * uppercase.
+ *
* Titlecasing requires knowledge about word boundaries, which is provided by
* the callback wbnext. A word boundary is the offset of the start of a word
* or the offset of the character immediately following a word.
@@ -98,9 +112,9 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
*/
size_t
unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- WordBoundaryNext wbnext, void *wbstate)
+ bool full, WordBoundaryNext wbnext, void *wbstate)
{
- return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, full, wbnext,
wbstate);
}
@@ -119,29 +133,42 @@ unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, full, NULL,
+ NULL);
}
/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
* If str_casekind is CaseLower or CaseUpper, map each character in the string
* for which a mapping is available.
*
- * If str_casekind is CaseTitle, maps characters found on a word boundary to
- * uppercase and other characters to lowercase.
+ * If str_casekind is CaseTitle: for each word boundary, "adjust" forward to
+ * the next Cased character and map it to titlecase; then map subsequent
+ * characters to lowercase until the next word boundary.
+ *
+ * Some characters have special mappings, which can map a single codepoint to
+ * multiple codepoints, or depend on conditions.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
+ void *wbstate)
{
/* character CaseKind varies while titlecasing */
CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
size_t boundary = 0;
+ bool adjusting = true;
Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
(str_casekind != CaseTitle && !wbnext && !wbstate));
@@ -156,21 +183,77 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
{
pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
- const pg_case_map *casemap = find_case_map(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+ /*
+ * Titlecasing has two states: adjusting from boundary (initial
+ * state), and lowercasing until the next boundary.
+ */
if (str_casekind == CaseTitle)
{
if (srcoff == boundary)
{
- chr_casekind = CaseUpper;
+ /* reset to initial state and find the next boundary */
+ adjusting = true;
boundary = wbnext(wbstate);
}
+
+ if (adjusting)
+ {
+ if (!full || pg_u_prop_cased(u1))
+ {
+ /* adjustment done: map to titlecase */
+ adjusting = false;
+ chr_casekind = full ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else
+ casemap = NULL; /* no mapping during adjustment */
+ }
else
+ {
chr_casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Note: only a single special mapping per codepoint is currently
+ * supported, though Unicode allows for multiple special mappings for
+ * a single codepoint.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
}
/* perform mapping, update result_len, and write to dst */
- if (casemap)
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[chr_casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
{
pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
@@ -198,6 +281,82 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
return result_len;
}
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
/* find entry in simple case map, if any */
static const pg_case_map *
find_case_map(pg_wchar ucs)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index c0c3382e79..c982815823 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -22,11 +22,11 @@ pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, WordBoundaryNext wbnext,
- void *wbstate);
+ ssize_t srclen, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
index b239f0b3c3..081d4133b1 100644
--- a/src/include/common/unicode_case_table.h
+++ b/src/include/common/unicode_case_table.h
@@ -20,6 +20,19 @@
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -28,2974 +41,3143 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
*/
-static const pg_case_map case_map[2955] =
+static const pg_case_map case_map[3003] =
{
/* begin dense entries for codepoints < 0x80 */
- {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}},
- {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}},
- {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}},
- {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}},
- {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}},
- {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}},
- {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}},
- {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}},
- {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}},
- {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}},
- {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}},
- {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}},
- {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}},
- {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}},
- {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}},
- {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}},
- {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}},
- {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}},
- {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}},
- {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}},
- {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}},
- {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}},
- {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}},
- {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}},
- {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}},
- {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}},
- {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}},
- {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}},
- {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}},
- {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}},
- {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}},
- {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}},
- {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}},
- {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}},
- {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}},
- {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}},
- {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}},
- {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}},
- {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}},
- {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}},
- {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}},
- {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}},
- {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}},
- {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}},
- {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}},
- {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}},
- {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}},
- {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}},
- {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}},
- {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}},
- {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}},
- {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}},
- {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}},
- {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}},
- {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}},
- {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}},
- {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}},
- {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}},
- {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}},
- {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}},
- {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}},
- {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}},
- {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}},
- {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}},
- {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}},
- {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}},
- {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}},
- {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}},
- {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}},
- {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}},
- {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}},
- {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}},
- {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}},
- {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}},
- {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}},
- {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}},
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
/* begin sparse entries for codepoints >= 0x80 */
- {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}},
- {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}},
- {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}},
- {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}},
- {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}},
- {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}},
- {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}},
- {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}},
- {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}},
- {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}},
- {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}},
- {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}},
- {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}},
- {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}},
- {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}},
- {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}},
- {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}},
- {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}},
- {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}},
- {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}},
- {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}},
- {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}},
- {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}},
- {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}},
- {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}},
- {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}},
- {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}},
- {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}},
- {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}},
- {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}},
- {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}},
- {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}},
- {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}},
- {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}},
- {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}},
- {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}},
- {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}},
- {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}},
- {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}},
- {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}},
- {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}},
- {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}},
- {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}},
- {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}},
- {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}},
- {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}},
- {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}},
- {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}},
- {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}},
- {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}},
- {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}},
- {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}},
- {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}},
- {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}},
- {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}},
- {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}},
- {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}},
- {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}},
- {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}},
- {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}},
- {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}},
- {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}},
- {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}},
- {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}},
- {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}},
- {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}},
- {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}},
- {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}},
- {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}},
- {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}},
- {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}},
- {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}},
- {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}},
- {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}},
- {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}},
- {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}},
- {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}},
- {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}},
- {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}},
- {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}},
- {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}},
- {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}},
- {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}},
- {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}},
- {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}},
- {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}},
- {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}},
- {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}},
- {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}},
- {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}},
- {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}},
- {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}},
- {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}},
- {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}},
- {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}},
- {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}},
- {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}},
- {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}},
- {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
- {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
};
--
2.34.1
[text/x-patch] v24-0005-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch (18.0K, ../../[email protected]/6-v24-0005-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch)
download | inline diff:
From fb66a4f669ccb0b6ea3c89723f733c3f9c294f6d Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 18:15:33 -0800
Subject: [PATCH v24 5/5] Support PG_UNICODE_FAST locale in the builtin
collation provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------ CATVERSION ------
The PG_UNICODE_FAST locale uses code point sort order (fast,
memcmp-based) combined with Unicode character semantics. The character
semantics are based on Unicode full case mapping.
Full case mapping can map a single codepoint to multiple codepoints,
such as "ß" uppercasing to "SS". Additionally, it handles
context-sensitive mappings like the "final sigma", and it uses
titlecase mappings such as "Dž" when titlecasing (rather than plain
uppercase mappings).
Importantly, the uppercasing of "ß" as "SS" is specifically mentioned
by the SQL standard. In Postgres, UCS_BASIC uses plain ASCII semantics
for case mapping and pattern matching, so if we changed it to use the
PG_UNICODE_FAST locale, it would offer better compliance with the
standard. For now, though, do not change the behavior of UCS_BASIC.
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 17 +++
src/backend/regex/regc_pg_locale.c | 11 +-
src/backend/utils/adt/formatting.c | 22 ++-
src/backend/utils/adt/pg_locale.c | 6 +
src/backend/utils/init/postinit.c | 1 +
src/bin/initdb/initdb.c | 6 +-
src/include/catalog/pg_collation.dat | 3 +
src/include/utils/pg_locale.h | 1 +
src/test/regress/expected/collate.utf8.out | 160 +++++++++++++++++++++
src/test/regress/sql/collate.utf8.sql | 60 ++++++++
10 files changed, 276 insertions(+), 11 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 55bbb20dac..fc520138a6 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -886,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_unicode_fast</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. It is only
+ available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>pg_c_utf8</literal></term>
<listitem>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 85f3238eb0..24c5200cef 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -78,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -271,7 +273,10 @@ pg_set_regex_collation(Oid collation)
if (pg_regex_locale)
{
if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = !pg_regex_locale->info.builtin.casemap_full;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
}
@@ -299,7 +304,7 @@ pg_wc_isdigit(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
case PG_REGEX_BUILTIN:
- return pg_u_isdigit(c, true);
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -367,7 +372,7 @@ pg_wc_isalnum(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
case PG_REGEX_BUILTIN:
- return pg_u_isalnum(c, true);
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -546,7 +551,7 @@ pg_wc_ispunct(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
case PG_REGEX_BUILTIN:
- return pg_u_ispunct(c, true);
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 97ccf23583..47601e75ba 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,15 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1844,15 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1927,6 +1931,7 @@ struct WordBoundaryState
size_t offset;
bool init;
bool prev_alnum;
+ bool posix;
};
/*
@@ -1943,7 +1948,7 @@ initcap_wbnext(void *state)
{
pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
- bool curr_alnum = pg_u_isalnum(u, true);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
{
@@ -2030,6 +2035,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
.offset = 0,
.init = false,
.prev_alnum = false,
+ .posix = !mylocale->info.builtin.casemap_full,
};
Assert(GetDatabaseEncoding() == PG_UTF8);
@@ -2038,7 +2044,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2056,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index a5aeabce94..ea88325f1c 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1596,6 +1596,7 @@ pg_newlocale_from_collation(Oid collid)
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
locstr);
+ result.info.builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
}
else if (collform->collprovider == COLLPROVIDER_LIBC)
{
@@ -2520,6 +2521,11 @@ builtin_validate_locale(int encoding, const char *locale)
required_encoding = PG_UTF8;
canonical_name = "C.UTF-8";
}
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ {
+ required_encoding = PG_UTF8;
+ canonical_name = "PG_UNICODE_FAST";
+ }
if (!canonical_name)
ereport(ERROR,
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 0805398e24..9a357e3f90 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -432,6 +432,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
default_locale.info.builtin.locale = MemoryContextStrdup(
TopMemoryContext, datlocale);
+ default_locale.info.builtin.casemap_full = (strcmp(datlocale, "PG_UNICODE_FAST") == 0);
}
else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ac33508d32..804cef35cb 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2408,6 +2408,8 @@ setlocales(void)
else if (strcmp(datlocale, "C.UTF-8") == 0 ||
strcmp(datlocale, "C.UTF8") == 0)
canonname = "C.UTF-8";
+ else if (strcmp(datlocale, "PG_UNICODE_FAST") == 0)
+ canonname = "PG_UNICODE_FAST";
else
pg_fatal("invalid locale name \"%s\" for builtin provider",
datlocale);
@@ -2703,7 +2705,9 @@ setup_locale_encoding(void)
if (locale_provider == COLLPROVIDER_BUILTIN)
{
- if (strcmp(datlocale, "C.UTF-8") == 0 && encodingid != PG_UTF8)
+ if ((strcmp(datlocale, "C.UTF-8") == 0 ||
+ strcmp(datlocale, "PG_UNICODE_FAST") == 0) &&
+ encodingid != PG_UTF8)
pg_fatal("builtin provider locale \"%s\" requires encoding \"%s\"",
datlocale, "UTF-8");
}
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index b95a89491d..a187b3dcef 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -33,5 +33,8 @@
{ oid => '811', descr => 'sorts by Unicode code point; Unicode & POSIX character semantics',
collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
colllocale => 'C.UTF-8' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST' },
]
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 3d949d5112..b924fdf653 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -79,6 +79,7 @@ struct pg_locale_struct
struct
{
const char *locale;
+ bool casemap_full;
} builtin;
locale_t lt;
#ifdef USE_ICU
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index eff0ef21ac..63327a8fdd 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -134,3 +134,163 @@ SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
t
(1 row)
+--
+-- Test PG_UNICODE_FAST
+--
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+ERROR: invalid locale name "unicode" for builtin provider
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123Abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_unicode_fast;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index 1f5f9ef491..c63928d38e 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -65,3 +65,63 @@ SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+
+--
+-- Test PG_UNICODE_FAST
+--
+
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+
+DROP TABLE test_pg_unicode_fast;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-14 08:54 ` Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
1 sibling, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-14 08:54 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 14.03.24 09:08, Jeff Davis wrote:
> On Wed, 2024-03-13 at 00:44 -0700, Jeff Davis wrote:
>> New series attached. I plan to commit 0001 very soon.
>
> Committed the basic builtin provider, supporting only the "C" locale.
As you were committing this, I had another review of
v23-0001-Introduce-collation-provider-builtin.patch in progress. Some
of the things I found you have already addressed in what you committed.
Please check the remaining comments.
* doc/src/sgml/charset.sgml
I don't understand the purpose of this sentence:
"When using this locale, the behavior may depend on the database encoding."
* doc/src/sgml/ref/create_database.sgml
The new parameter builtin_locale is not documented.
* src/backend/commands/collationcmds.c
I think DefineCollation() should set collencoding = -1 for the
COLLPROVIDER_BUILTIN case. -1 stands for any encoding. Or at least
explain why not?
* src/backend/utils/adt/pg_locale.c
This part is a bit confusing:
+ cache_entry->collate_is_c = true;
+ cache_entry->ctype_is_c = (strcmp(colllocale, "C") == 0);
Is collate always C but ctype only sometimes? Does this anticipate
future patches in this series? Maybe in this patch it should always
be true?
* src/bin/initdb/initdb.c
+ printf(_(" --builtin-locale=LOCALE set builtin locale name
for new databases\n"));
Put in a line break so that the right "column" lines up.
This output should line up better:
The database cluster will be initialized with this locale configuration:
default collation provider: icu
default collation locale: en
LC_COLLATE: C
LC_CTYPE: C
...
Also, why are there two spaces after "provider: "?
Also we call these locale provider on input, why are they collation
providers on output? What is a "collation locale"?
* src/bin/pg_upgrade/t/002_pg_upgrade.pl
+if ($oldnode->pg_version >= '17devel')
This is weird. >= is a numeric comparison, so providing a string with
non-digits is misleading at best.
* src/test/icu/t/010_database.pl
-# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
-# are specified
Why remove this test?
+my ($ret, $stdout, $stderr) = $node1->psql('postgres',
+ q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE
dbicu}
+);
Change the name of the new database to be different from the name of
the template database.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-03-14 20:42 ` Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
0 siblings, 2 replies; 94+ messages in thread
From: Jeff Davis @ 2024-03-14 20:42 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Thu, 2024-03-14 at 09:54 +0100, Peter Eisentraut wrote:
> * doc/src/sgml/charset.sgml
>
> I don't understand the purpose of this sentence:
>
> "When using this locale, the behavior may depend on the database
> encoding."
The "C" locale (in either the builtin or libc provider) can sort
differently in different encodings, because it's based on memcmp. For
instance:
select U&'\20AC' > U&'\201A' collate "C";
Returns true in UTF-8 and false in WIN1252. That's why UCS_BASIC is
only available in UTF-8, because (at least for some encodings) we'd
have to decode before comparison to get the code-point-order semantics
right.
In other words, the "C" collation is not a well-defined order, but
UCS_BASIC and C.UTF-8 are well-defined.
Suggestions for better wording are welcome.
> * doc/src/sgml/ref/create_database.sgml
>
> The new parameter builtin_locale is not documented.
Thank you, fixed in 0001 (review fixup).
> * src/backend/commands/collationcmds.c
>
> I think DefineCollation() should set collencoding = -1 for the
> COLLPROVIDER_BUILTIN case. -1 stands for any encoding. Or at least
> explain why not?
In the attached v25-0001 (review fixup) I have made it the
responsibility of a function, and then extended that for the C.UTF-8
(0002) and PG_UNICODE_FAST locales (0007).
> * src/backend/utils/adt/pg_locale.c
>
> This part is a bit confusing:
>
> + cache_entry->collate_is_c = true;
> + cache_entry->ctype_is_c = (strcmp(colllocale, "C") == 0);
>
> Is collate always C but ctype only sometimes? Does this anticipate
> future patches in this series? Maybe in this patch it should always
> be true?
Made it a constant in v25-0001, and changed it in 0002
>
> * src/bin/initdb/initdb.c
>
> + printf(_(" --builtin-locale=LOCALE set builtin locale name
> for new databases\n"));
>
> Put in a line break so that the right "column" lines up.
Fixed in 0001
> This output should line up better:
>
> The database cluster will be initialized with this locale
> configuration:
> default collation provider: icu
> default collation locale: en
> LC_COLLATE: C
> LC_CTYPE: C
> ...
>
> Also, why are there two spaces after "provider: "?
>
> Also we call these locale provider on input, why are they collation
> providers on output? What is a "collation locale"?
I tried to fix these things in 0001.
> * src/bin/pg_upgrade/t/002_pg_upgrade.pl
>
> +if ($oldnode->pg_version >= '17devel')
>
> This is weird. >= is a numeric comparison, so providing a string
> with
> non-digits is misleading at best.
It's actually not a numeric comparison, it's an overloaded comparison
op for the Version class.
See 32dd2c1eff and:
https://www.postgresql.org/message-id/1738174.1710274577%40sss.pgh.pa.us
> * src/test/icu/t/010_database.pl
>
> -# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
> -# are specified
>
> Why remove this test?
It must have been lost during a rebase, fixed in 0001.
> Change the name of the new database to be different from the name of
> the template database.
Fixed in 0001.
New series attached.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v25-0001-Address-more-review-comments-on-commit-2d819a08a.patch (7.9K, ../../[email protected]/2-v25-0001-Address-more-review-comments-on-commit-2d819a08a.patch)
download | inline diff:
From e50d0fb79904accf1c26a77fb27980b8c398fc05 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 14 Mar 2024 11:18:55 -0700
Subject: [PATCH v25 1/7] Address more review comments on commit 2d819a08a1.
* Document CREATE DATABASE ... BUILTIN_LOCALE.
* Determine required encoding based on locale name for CREATE
COLLATION.
* initdb output fixups.
* Make ctype_is_c a constant true for now.
* Fixups to ICU 010_create_database.pl test.
Discussion: https://postgr.es/m/[email protected]
Reviewed-by: Peter Eisentraut
---
doc/src/sgml/ref/create_database.sgml | 16 ++++++++++++++
src/backend/commands/collationcmds.c | 2 +-
src/backend/utils/adt/pg_locale.c | 31 ++++++++++++++++++++-------
src/bin/initdb/initdb.c | 7 +++---
src/include/utils/pg_locale.h | 1 +
src/test/icu/t/010_database.pl | 12 ++++++++++-
6 files changed, 56 insertions(+), 13 deletions(-)
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 6c1fd95602..d02ba5ce4d 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -29,6 +29,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
[ LOCALE [=] <replaceable class="parameter">locale</replaceable> ]
[ LC_COLLATE [=] <replaceable class="parameter">lc_collate</replaceable> ]
[ LC_CTYPE [=] <replaceable class="parameter">lc_ctype</replaceable> ]
+ [ BUILTIN_LOCALE [=] <replaceable class="parameter">builtin_locale</replaceable> ]
[ ICU_LOCALE [=] <replaceable class="parameter">icu_locale</replaceable> ]
[ ICU_RULES [=] <replaceable class="parameter">icu_rules</replaceable> ]
[ LOCALE_PROVIDER [=] <replaceable class="parameter">locale_provider</replaceable> ]
@@ -216,6 +217,21 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
</listitem>
</varlistentry>
+ <varlistentry id="create-database-builtin-locale">
+ <term><replaceable class="parameter">builtin_locale</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the builtin provider locale for the database default
+ collation order and character classification, overriding the setting
+ <xref linkend="create-database-locale"/>. The <link
+ linkend="create-database-locale-provider">locale provider</link> must
+ be <literal>builtin</literal>. The default is the setting of <xref
+ linkend="create-database-locale"/> if specified; otherwise the same
+ setting as the template database.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="create-database-icu-locale">
<term><replaceable class="parameter">icu_locale</replaceable></term>
<listitem>
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 9059f8b3ef..63ef9a0841 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -318,7 +318,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
if (collprovider == COLLPROVIDER_BUILTIN)
{
- collencoding = GetDatabaseEncoding();
+ collencoding = builtin_locale_encoding(colllocale);
}
else if (collprovider == COLLPROVIDER_ICU)
{
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 39390fbe4e..31de58b38b 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1270,14 +1270,8 @@ lookup_collation_cache(Oid collation, bool set_flags)
if (collform->collprovider == COLLPROVIDER_BUILTIN)
{
- Datum datum;
- const char *colllocale;
-
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
- colllocale = TextDatumGetCString(datum);
-
cache_entry->collate_is_c = true;
- cache_entry->ctype_is_c = (strcmp(colllocale, "C") == 0);
+ cache_entry->ctype_is_c = true;
}
else if (collform->collprovider == COLLPROVIDER_LIBC)
{
@@ -2501,11 +2495,32 @@ pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
return result;
}
+/*
+ * Return required encoding ID for the given locale, or -1 if any encoding is
+ * valid for the locale.
+ */
+int
+builtin_locale_encoding(const char *locale)
+{
+ if (strcmp(locale, "C") == 0)
+ return -1;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ locale)));
+}
+
+
+/*
+ * Validate the locale and encoding combination, and return the canonical form
+ * of the locale name.
+ */
const char *
builtin_validate_locale(int encoding, const char *locale)
{
const char *canonical_name = NULL;
- int required_encoding = -1;
+ int required_encoding = builtin_locale_encoding(locale);
if (strcmp(locale, "C") == 0)
canonical_name = "C";
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 8d53ef4a1f..c2daff1717 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2455,7 +2455,8 @@ usage(const char *progname)
" set default locale in the respective category for\n"
" new databases (default taken from environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
- printf(_(" --builtin-locale=LOCALE set builtin locale name for new databases\n"));
+ printf(_(" --builtin-locale=LOCALE\n"
+ " set builtin locale name for new databases\n"));
printf(_(" --locale-provider={builtin|libc|icu}\n"
" set default locale provider for new databases\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
@@ -2618,9 +2619,9 @@ setup_locale_encoding(void)
else
{
printf(_("The database cluster will be initialized with this locale configuration:\n"));
- printf(_(" default collation provider: %s\n"), collprovider_name(locale_provider));
+ printf(_(" locale provider: %s\n"), collprovider_name(locale_provider));
if (locale_provider != COLLPROVIDER_LIBC)
- printf(_(" default collation locale: %s\n"), datlocale);
+ printf(_(" default collation: %s\n"), datlocale);
printf(_(" LC_COLLATE: %s\n"
" LC_CTYPE: %s\n"
" LC_MESSAGES: %s\n"
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 3d949d5112..205aa20067 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -117,6 +117,7 @@ extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
size_t srclen, pg_locale_t locale);
+extern int builtin_locale_encoding(const char *loc_str);
extern const char *builtin_validate_locale(int encoding, const char *loc_str);
extern void icu_validate_locale(const char *loc_str);
extern char *icu_language_tag(const char *loc_str, int elevel);
diff --git a/src/test/icu/t/010_database.pl b/src/test/icu/t/010_database.pl
index 5f8ef16803..88d91cca39 100644
--- a/src/test/icu/t/010_database.pl
+++ b/src/test/icu/t/010_database.pl
@@ -62,8 +62,18 @@ is( $node1->psql(
0,
"C locale works for ICU");
+# Test that LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE
+# are specified
+is( $node1->psql(
+ 'postgres',
+ q{CREATE DATABASE dbicu2 LOCALE_PROVIDER icu LOCALE '@colStrength=primary'
+ LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0 ENCODING UTF8}
+ ),
+ 0,
+ "LOCALE works for ICU locales if LC_COLLATE and LC_CTYPE are specified");
+
my ($ret, $stdout, $stderr) = $node1->psql('postgres',
- q{CREATE DATABASE dbicu LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
+ q{CREATE DATABASE dbicu3 LOCALE_PROVIDER builtin LOCALE 'C' TEMPLATE dbicu}
);
isnt($ret, 0, "locale provider must match template: exit code not 0");
like(
--
2.34.1
[text/x-patch] v25-0002-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch (29.8K, ../../[email protected]/3-v25-0002-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch)
download | inline diff:
From 5d803ef4ce4abc17285715589779b3e4af2e905d Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 17:41:51 -0800
Subject: [PATCH v25 2/7] Support C.UTF-8 locale in the new builtin collation
provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
----- CATVERSION -----
The builtin C.UTF-8 locale has similar semantics to the libc locale of
the same name. That is, code point sort order (fast, memcmp-based)
combined with Unicode semantics for character operations such as
pattern matching, regular expressions, and
LOWER()/INITCAP()/UPPER(). The character semantics are based on
Unicode simple case mappings.
The builtin provider's C.UTF-8 offers several important advantages
over libc:
* faster sorting -- benefits from additional optimizations such as
abbreviated keys and varstrfastcmp_c
* faster case conversion, e.g. LOWER(), at least compared with some
libc implementations
* available on all platforms with identical semantics, and the
semantics are stable, testable, and documentable within a given
Postgres major version
Being based on memcmp, the builtin C.UTF-8 locale does not offer
natural language sort order. But it is an improvement for most use
cases that might otherwise use libc's "C.UTF-8" locale, as well as
many use cases that use libc's "C" locale.
Discussion: https://postgr.es/m/ff4c2f2f9c8fc7ca27c1c24ae37ecaeaeaff6b53.camel%40j-davis.com
Reviewed-by: Daniel Vérité, Peter Eisentraut, Jeremy Schneider
---
doc/src/sgml/charset.sgml | 27 +++-
doc/src/sgml/ref/create_collation.sgml | 2 +-
doc/src/sgml/ref/create_database.sgml | 3 +-
doc/src/sgml/ref/initdb.sgml | 2 +-
src/backend/regex/regc_pg_locale.c | 36 ++++-
src/backend/utils/adt/formatting.c | 123 +++++++++++++++++
src/backend/utils/adt/pg_locale.c | 24 +++-
src/bin/initdb/initdb.c | 16 ++-
src/bin/initdb/t/001_initdb.pl | 19 ++-
src/bin/pg_upgrade/t/002_pg_upgrade.pl | 2 +-
src/bin/scripts/t/020_createdb.pl | 18 +++
src/include/catalog/pg_collation.dat | 3 +
src/test/regress/expected/collate.utf8.out | 136 +++++++++++++++++++
src/test/regress/expected/collate.utf8_1.out | 8 ++
src/test/regress/parallel_schedule | 4 +-
src/test/regress/sql/collate.utf8.sql | 67 +++++++++
16 files changed, 476 insertions(+), 14 deletions(-)
create mode 100644 src/test/regress/expected/collate.utf8.out
create mode 100644 src/test/regress/expected/collate.utf8_1.out
create mode 100644 src/test/regress/sql/collate.utf8.sql
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 7114eb7b52..55bbb20dac 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -377,13 +377,21 @@ initdb --locale-provider=icu --icu-locale=en
<listitem>
<para>
The <literal>builtin</literal> provider uses built-in operations. Only
- the <literal>C</literal> locale is supported for this provider.
+ the <literal>C</literal> and <literal>C.UTF-8</literal> locales are
+ supported for this provider.
</para>
<para>
The <literal>C</literal> locale behavior is identical to the
<literal>C</literal> locale in the libc provider. When using this
locale, the behavior may depend on the database encoding.
</para>
+ <para>
+ The <literal>C.UTF-8</literal> locale is available only for when the
+ database encoding is <literal>UTF-8</literal>, and the behavior is
+ based on Unicode. The collation uses the code point values only. The
+ regular expression character classes are based on the "POSIX
+ Compatible" semantics, and the case mapping is the "simple" variant.
+ </para>
</listitem>
</varlistentry>
@@ -878,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_c_utf8</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function>, it uses
+ Unicode simple case mapping. For pattern matching (including regular
+ expressions), it uses the POSIX Compatible variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. This collation is
+ only available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>C</literal> (equivalent to <literal>POSIX</literal>)</term>
<listitem>
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 98cd7d56be..85f18cbbe5 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -99,7 +99,7 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<para>
If <replaceable>provider</replaceable> is <literal>builtin</literal>,
then <replaceable>locale</replaceable> must be specified and set to
- <literal>C</literal>.
+ either <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index d02ba5ce4d..68e95b4420 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -166,7 +166,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
<para>
If <xref linkend="create-database-locale-provider"/> is
<literal>builtin</literal>, then <replaceable>locale</replaceable>
- must be specified and set to <literal>C</literal>.
+ must be specified and set to either <literal>C</literal> or
+ <literal>C.UTF-8</literal>.
</para>
<tip>
<para>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index 4760570f6a..08a1c2538f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -289,7 +289,7 @@ PostgreSQL documentation
<para>
If <option>--locale-provider</option> is <literal>builtin</literal>,
<option>--locale</option> must be specified and set to
- <literal>C</literal>.
+ <literal>C</literal> or <literal>C.UTF-8</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 6a26388bfa..85f3238eb0 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -16,6 +16,8 @@
*/
#include "catalog/pg_collation.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "utils/pg_locale.h"
/*
@@ -64,6 +66,7 @@
typedef enum
{
PG_REGEX_LOCALE_C, /* C locale (encoding independent) */
+ PG_REGEX_BUILTIN, /* built-in Unicode semantics */
PG_REGEX_LOCALE_WIDE, /* Use <wctype.h> functions */
PG_REGEX_LOCALE_1BYTE, /* Use <ctype.h> functions */
PG_REGEX_LOCALE_WIDE_L, /* Use locale_t <wctype.h> functions */
@@ -266,7 +269,12 @@ pg_set_regex_collation(Oid collation)
if (GetDatabaseEncoding() == PG_UTF8)
{
if (pg_regex_locale)
- pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ {
+ if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ pg_regex_strategy = PG_REGEX_BUILTIN;
+ else
+ pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE;
}
@@ -290,6 +298,8 @@ pg_wc_isdigit(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isdigit(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -322,6 +332,8 @@ pg_wc_isalpha(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALPHA));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalpha(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalpha((wint_t) c);
@@ -354,6 +366,8 @@ pg_wc_isalnum(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isalnum(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -395,6 +409,8 @@ pg_wc_isupper(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISUPPER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isupper(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswupper((wint_t) c);
@@ -427,6 +443,8 @@ pg_wc_islower(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISLOWER));
+ case PG_REGEX_BUILTIN:
+ return pg_u_islower(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswlower((wint_t) c);
@@ -459,6 +477,8 @@ pg_wc_isgraph(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISGRAPH));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isgraph(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswgraph((wint_t) c);
@@ -491,6 +511,8 @@ pg_wc_isprint(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPRINT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isprint(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswprint((wint_t) c);
@@ -523,6 +545,8 @@ pg_wc_ispunct(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
+ case PG_REGEX_BUILTIN:
+ return pg_u_ispunct(c, true);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
@@ -555,6 +579,8 @@ pg_wc_isspace(pg_wchar c)
case PG_REGEX_LOCALE_C:
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISSPACE));
+ case PG_REGEX_BUILTIN:
+ return pg_u_isspace(c);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswspace((wint_t) c);
@@ -588,6 +614,8 @@ pg_wc_toupper(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_toupper((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_uppercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -628,6 +656,8 @@ pg_wc_tolower(pg_wchar c)
if (c <= (pg_wchar) 127)
return pg_ascii_tolower((unsigned char) c);
return c;
+ case PG_REGEX_BUILTIN:
+ return unicode_lowercase_simple(c);
case PG_REGEX_LOCALE_WIDE:
/* force C behavior for ASCII characters, per comments above */
if (c <= (pg_wchar) 127)
@@ -792,6 +822,9 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
#endif
break;
+ case PG_REGEX_BUILTIN:
+ max_chr = (pg_wchar) MAX_SIMPLE_CHR;
+ break;
case PG_REGEX_LOCALE_WIDE:
case PG_REGEX_LOCALE_WIDE_L:
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
@@ -809,6 +842,7 @@ pg_ctype_get_cache(pg_wc_probefunc probefunc, int cclasscode)
max_chr = (pg_wchar) MAX_SIMPLE_CHR;
break;
default:
+ Assert(false);
max_chr = 0; /* can't get here, but keep compiler quiet */
break;
}
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 5f483b8dbc..1a578b8a2b 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -77,6 +77,8 @@
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
+#include "common/unicode_case.h"
+#include "common/unicode_category.h"
#include "mb/pg_wchar.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
@@ -1679,6 +1681,33 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strlower(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1799,6 +1828,33 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
+
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ if (needed + 1 > dstsize)
+ {
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strupper(dst, dstsize, src, srclen);
+ Assert(needed + 1 == dstsize);
+ }
+
+ result = dst;
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
@@ -1920,6 +1976,73 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
}
else
#endif
+ if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
+ {
+ const unsigned char *src = (unsigned char *) buff;
+ unsigned char *dst;
+ size_t dstsize = nbytes + 1;
+ int srcoff = 0;
+ int dstoff = 0;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ /* Output workspace cannot have more codes than input bytes */
+ dst = (unsigned char *) palloc(dstsize);
+
+ while (srcoff < nbytes)
+ {
+ pg_wchar u1 = utf8_to_unicode(src + srcoff);
+ pg_wchar u2;
+ int u1len = unicode_utf8len(u1);
+ int u2len;
+
+ if (wasalnum)
+ u2 = unicode_lowercase_simple(u1);
+ else
+ u2 = unicode_uppercase_simple(u1);
+
+ u2len = unicode_utf8len(u2);
+
+ wasalnum = pg_u_isalnum(u2, true);
+
+ /*
+ * If we can't fit the necessary bytes and a terminating NUL,
+ * reallocate buffer to the maximum size we might need, and
+ * shrink it later.
+ */
+ if (dstoff + u2len + 1 > dstsize)
+ {
+ /* Overflow paranoia */
+ if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ dstsize = (nbytes + 1) * sizeof(pg_wchar);
+ dst = repalloc(dst, dstsize);
+ }
+
+ unicode_to_utf8(u2, dst + dstoff);
+ srcoff += u1len;
+ dstoff += u2len;
+ }
+
+ *(dst + dstoff) = '\0';
+ dstoff++;
+
+ if (dstsize == dstoff)
+ {
+ result = (char *) dst;
+ }
+ else
+ {
+ /* shrink buffer and store result */
+ result = palloc(dstoff);
+ memcpy(result, dst, dstoff);
+ pfree(dst);
+ }
+ }
+ else
{
Assert(!mylocale || mylocale->provider == COLLPROVIDER_LIBC);
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 31de58b38b..0ea79f9b4f 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1270,8 +1270,14 @@ lookup_collation_cache(Oid collation, bool set_flags)
if (collform->collprovider == COLLPROVIDER_BUILTIN)
{
+ Datum datum;
+ const char *colllocale;
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
+ colllocale = TextDatumGetCString(datum);
+
cache_entry->collate_is_c = true;
- cache_entry->ctype_is_c = true;
+ cache_entry->ctype_is_c = (strcmp(colllocale, "C") == 0);
}
else if (collform->collprovider == COLLPROVIDER_LIBC)
{
@@ -1670,7 +1676,6 @@ pg_newlocale_from_collation(Oid collid)
collversionstr = TextDatumGetCString(datum);
- Assert(collform->collprovider != COLLPROVIDER_BUILTIN);
if (collform->collprovider == COLLPROVIDER_LIBC)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
else
@@ -1725,7 +1730,13 @@ get_collation_actual_version(char collprovider, const char *collcollate)
{
char *collversion = NULL;
- /* the builtin collation provider is not versioned */
+ /*
+ * The only two supported locales (C and C.UTF-8) are both based on memcmp
+ * and are not expected to change.
+ *
+ * Note that the character semantics may change for some locales, but the
+ * collation version only tracks changes to sort order.
+ */
if (collprovider == COLLPROVIDER_BUILTIN)
return NULL;
@@ -2504,6 +2515,8 @@ builtin_locale_encoding(const char *locale)
{
if (strcmp(locale, "C") == 0)
return -1;
+ if (strcmp(locale, "C.UTF-8") == 0)
+ return PG_UTF8;
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -2520,10 +2533,12 @@ const char *
builtin_validate_locale(int encoding, const char *locale)
{
const char *canonical_name = NULL;
- int required_encoding = builtin_locale_encoding(locale);
+ int required_encoding;
if (strcmp(locale, "C") == 0)
canonical_name = "C";
+ else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
+ canonical_name = "C.UTF-8";
if (!canonical_name)
ereport(ERROR,
@@ -2531,6 +2546,7 @@ builtin_validate_locale(int encoding, const char *locale)
errmsg("invalid locale name \"%s\" for builtin provider",
locale)));
+ required_encoding = builtin_locale_encoding(canonical_name);
if (required_encoding >= 0 && encoding != required_encoding)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index c2daff1717..30e17bd1d1 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2403,9 +2403,16 @@ setlocales(void)
if (locale_provider == COLLPROVIDER_BUILTIN)
{
- if (strcmp(datlocale, "C") != 0)
+ if (strcmp(datlocale, "C") == 0)
+ canonname = "C";
+ else if (strcmp(datlocale, "C.UTF-8") == 0 ||
+ strcmp(datlocale, "C.UTF8") == 0)
+ canonname = "C.UTF-8";
+ else
pg_fatal("invalid locale name \"%s\" for builtin provider",
datlocale);
+
+ datlocale = canonname;
}
else if (locale_provider == COLLPROVIDER_ICU)
{
@@ -2695,6 +2702,13 @@ setup_locale_encoding(void)
!check_locale_encoding(lc_collate, encodingid))
exit(1); /* check_locale_encoding printed the error */
+ if (locale_provider == COLLPROVIDER_BUILTIN)
+ {
+ if (strcmp(datlocale, "C.UTF-8") == 0 && encodingid != PG_UTF8)
+ pg_fatal("builtin provider locale \"%s\" requires encoding \"%s\"",
+ datlocale, "UTF-8");
+ }
+
if (locale_provider == COLLPROVIDER_ICU &&
!check_icu_locale_encoding(encodingid))
exit(1);
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index e719f70dae..c63d3206d9 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -138,7 +138,7 @@ if ($ENV{with_icu} eq 'yes')
'--lc-monetary=C', '--lc-time=C',
"$tempdir/data4"
],
- qr/^\s+default collation locale:\s+und\n/ms,
+ qr/^\s+default collation:\s+und\n/ms,
'options --locale-provider=icu --locale=und --lc-*=C');
command_fails_like(
@@ -196,6 +196,23 @@ command_ok(
],
'locale provider builtin with --locale');
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
+
+command_fails(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E SQL_ASCII',
+ '--builtin-locale=C.UTF-8', "$tempdir/data9"
+ ],
+ 'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
+);
+
command_ok(
[
'initdb', '--no-sync',
diff --git a/src/bin/pg_upgrade/t/002_pg_upgrade.pl b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
index ed79c0930b..3e67121a8d 100644
--- a/src/bin/pg_upgrade/t/002_pg_upgrade.pl
+++ b/src/bin/pg_upgrade/t/002_pg_upgrade.pl
@@ -140,7 +140,7 @@ if ($oldnode->pg_version >= '17devel')
{
$original_enc_name = "UTF-8";
$original_provider = "b";
- $original_datlocale = "C";
+ $original_datlocale = "C.UTF-8";
}
elsif ($oldnode->pg_version >= 15 && $ENV{with_icu} eq 'yes')
{
diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl
index dfd635bfab..0b371ea4df 100644
--- a/src/bin/scripts/t/020_createdb.pl
+++ b/src/bin/scripts/t/020_createdb.pl
@@ -139,6 +139,24 @@ $node->command_ok(
],
'create database with provider "builtin" and LC_CTYPE=C');
+$node->command_ok(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E UTF-8', '--builtin-locale=C.UTF8',
+ 'tbuiltin5'
+ ],
+ 'create database with --builtin-locale C.UTF-8 and -E UTF-8');
+
+$node->command_fails(
+ [
+ 'createdb', '-T',
+ 'template0', '--locale-provider=builtin',
+ '-E LATIN1', '--builtin-locale=C.UTF-8',
+ 'tbuiltin6'
+ ],
+ 'create database with --builtin-locale C.UTF-8 and -E LATIN1');
+
$node->command_fails(
[
'createdb', '-T',
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 938432e8a4..083b0cdcca 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -30,5 +30,8 @@
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
+{ oid => '811', descr => 'sorts by Unicode code point; Unicode and POSIX character semantics',
+ collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
+ colllocale => 'C.UTF-8' },
]
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
new file mode 100644
index 0000000000..eff0ef21ac
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8.out
@@ -0,0 +1,136 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+SET client_encoding TO UTF8;
+--
+-- Test PG_C_UTF8
+--
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C_UTF8'); -- fails
+ERROR: invalid locale name "C_UTF8" for builtin provider
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF8');
+DROP COLLATION regress_pg_c_utf8;
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF-8');
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+-----------------+-----------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs ßss Déf | ÁBC SßS ßSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | DŽxxdž DŽxxdž DŽxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_c_utf8;
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+ lower
+-------
+ ασ
+(1 row)
+
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+ lower
+-------
+ αͺσͺ
+(1 row)
+
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+ lower
+-------
+ α΄σ΄
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/expected/collate.utf8_1.out b/src/test/regress/expected/collate.utf8_1.out
new file mode 100644
index 0000000000..e73fdf50c3
--- /dev/null
+++ b/src/test/regress/expected/collate.utf8_1.out
@@ -0,0 +1,8 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 1d8a414eea..e48cb4b7a3 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -78,9 +78,9 @@ test: brin_bloom brin_multi
# psql depends on create_am
# amutils depends on geometry, create_index_spgist, hash_index, brin
# ----------
-test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps
+test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.utf8 collate.icu.utf8 incremental_sort create_role without_overlaps
-# collate.*.utf8 tests cannot be run in parallel with each other
+# collate.linux.utf8 and collate.icu.utf8 tests cannot be run in parallel with each other
test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252
# ----------
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
new file mode 100644
index 0000000000..1f5f9ef491
--- /dev/null
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -0,0 +1,67 @@
+/*
+ * This test is for collations and character operations when using the
+ * builtin provider with the C.UTF-8 locale.
+ */
+
+/* skip test if not UTF8 server encoding */
+SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+
+SET client_encoding TO UTF8;
+
+--
+-- Test PG_C_UTF8
+--
+
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C_UTF8'); -- fails
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF8');
+DROP COLLATION regress_pg_c_utf8;
+CREATE COLLATION regress_pg_c_utf8 (
+ provider = builtin, locale = 'C.UTF-8');
+
+CREATE TABLE test_pg_c_utf8 (
+ t TEXT COLLATE PG_C_UTF8
+);
+INSERT INTO test_pg_c_utf8 VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_c_utf8;
+
+DROP TABLE test_pg_c_utf8;
+
+-- negative test: Final_Sigma not used for builtin locale C.UTF-8
+SELECT lower('ΑΣ' COLLATE PG_C_UTF8);
+SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8);
+SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8);
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8;
+SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; -- symbols are punctuation in posix
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8;
+SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; -- only 0-9 considered digits in posix
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
--
2.34.1
[text/x-patch] v25-0003-Inline-basic-UTF-8-functions.patch (4.4K, ../../[email protected]/4-v25-0003-Inline-basic-UTF-8-functions.patch)
download | inline diff:
From 7b10bbbef55b38668e1530aac997944cfad69b1e Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 2 Mar 2024 11:27:23 -0800
Subject: [PATCH v25 3/7] Inline basic UTF-8 functions.
Shows a measurable speedup when processing UTF-8 data, such as with
the new builtin collation provider.
Discussion: https://postgr.es/m/[email protected]
---
src/common/wchar.c | 61 ---------------------------------------
src/include/mb/pg_wchar.h | 61 +++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 61 deletions(-)
diff --git a/src/common/wchar.c b/src/common/wchar.c
index a238c0106c..76b7dfdfcb 100644
--- a/src/common/wchar.c
+++ b/src/common/wchar.c
@@ -476,39 +476,6 @@ pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len)
}
-/*
- * Map a Unicode code point to UTF-8. utf8string must have at least
- * unicode_utf8len(c) bytes available.
- */
-unsigned char *
-unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
-{
- if (c <= 0x7F)
- {
- utf8string[0] = c;
- }
- else if (c <= 0x7FF)
- {
- utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
- utf8string[1] = 0x80 | (c & 0x3F);
- }
- else if (c <= 0xFFFF)
- {
- utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
- utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[2] = 0x80 | (c & 0x3F);
- }
- else
- {
- utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
- utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
- utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
- utf8string[3] = 0x80 | (c & 0x3F);
- }
-
- return utf8string;
-}
-
/*
* Trivial conversion from pg_wchar to UTF-8.
* caller should allocate enough space for "to"
@@ -670,34 +637,6 @@ ucs_wcwidth(pg_wchar ucs)
return 1;
}
-/*
- * Convert a UTF-8 character to a Unicode code point.
- * This is a one-character version of pg_utf2wchar_with_len.
- *
- * No error checks here, c must point to a long-enough string.
- */
-pg_wchar
-utf8_to_unicode(const unsigned char *c)
-{
- if ((*c & 0x80) == 0)
- return (pg_wchar) c[0];
- else if ((*c & 0xe0) == 0xc0)
- return (pg_wchar) (((c[0] & 0x1f) << 6) |
- (c[1] & 0x3f));
- else if ((*c & 0xf0) == 0xe0)
- return (pg_wchar) (((c[0] & 0x0f) << 12) |
- ((c[1] & 0x3f) << 6) |
- (c[2] & 0x3f));
- else if ((*c & 0xf8) == 0xf0)
- return (pg_wchar) (((c[0] & 0x07) << 18) |
- ((c[1] & 0x3f) << 12) |
- ((c[2] & 0x3f) << 6) |
- (c[3] & 0x3f));
- else
- /* that is an invalid code on purpose */
- return 0xffffffff;
-}
-
static int
pg_utf_dsplen(const unsigned char *s)
{
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 69a55b66f4..249cd18a35 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -555,6 +555,67 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
+/*
+ * Convert a UTF-8 character to a Unicode code point.
+ * This is a one-character version of pg_utf2wchar_with_len.
+ *
+ * No error checks here, c must point to a long-enough string.
+ */
+static inline pg_wchar
+utf8_to_unicode(const unsigned char *c)
+{
+ if ((*c & 0x80) == 0)
+ return (pg_wchar) c[0];
+ else if ((*c & 0xe0) == 0xc0)
+ return (pg_wchar) (((c[0] & 0x1f) << 6) |
+ (c[1] & 0x3f));
+ else if ((*c & 0xf0) == 0xe0)
+ return (pg_wchar) (((c[0] & 0x0f) << 12) |
+ ((c[1] & 0x3f) << 6) |
+ (c[2] & 0x3f));
+ else if ((*c & 0xf8) == 0xf0)
+ return (pg_wchar) (((c[0] & 0x07) << 18) |
+ ((c[1] & 0x3f) << 12) |
+ ((c[2] & 0x3f) << 6) |
+ (c[3] & 0x3f));
+ else
+ /* that is an invalid code on purpose */
+ return 0xffffffff;
+}
+
+/*
+ * Map a Unicode code point to UTF-8. utf8string must have at least
+ * unicode_utf8len(c) bytes available.
+ */
+static inline unsigned char *
+unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
+{
+ if (c <= 0x7F)
+ {
+ utf8string[0] = c;
+ }
+ else if (c <= 0x7FF)
+ {
+ utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
+ utf8string[1] = 0x80 | (c & 0x3F);
+ }
+ else if (c <= 0xFFFF)
+ {
+ utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
+ utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[2] = 0x80 | (c & 0x3F);
+ }
+ else
+ {
+ utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
+ utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
+ utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
+ utf8string[3] = 0x80 | (c & 0x3F);
+ }
+
+ return utf8string;
+}
+
/*
* Number of bytes needed to represent the given char in UTF8.
*/
--
2.34.1
[text/x-patch] v25-0004-Use-version-for-builtin-collations.patch (1.8K, ../../[email protected]/5-v25-0004-Use-version-for-builtin-collations.patch)
download | inline diff:
From 3789f5d6483b650f4957d358d6974108c6c0b260 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 14 Mar 2024 12:07:45 -0700
Subject: [PATCH v25 4/7] Use version for builtin collations.
------ CATVERSION ------
Even though we don't expect any changes to memcmp() semantics, it's
plausible that the surrounding optimizations (such as abbreviated
keys, or future optimizations that don't exist today) may have bugs.
Given that the version field already exists, there's little reason not
to use it. Suggestion from Peter Eisentraut.
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/pg_locale.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 0ea79f9b4f..793984053f 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1732,13 +1732,25 @@ get_collation_actual_version(char collprovider, const char *collcollate)
/*
* The only two supported locales (C and C.UTF-8) are both based on memcmp
- * and are not expected to change.
+ * and are not expected to change. However, track version anyway, which
+ * may be useful in the event of bugs.
*
* Note that the character semantics may change for some locales, but the
* collation version only tracks changes to sort order.
*/
if (collprovider == COLLPROVIDER_BUILTIN)
- return NULL;
+ {
+ Assert(collcollate != NULL);
+ if (strcmp(collcollate, "C") == 0)
+ return "1.0";
+ else if (strcmp(collcollate, "C.UTF-8") == 0)
+ return "1.0";
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ collcollate)));
+ }
#ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU)
--
2.34.1
[text/x-patch] v25-0005-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch (9.4K, ../../[email protected]/6-v25-0005-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch)
download | inline diff:
From 5763d9f8fe44b7560246186795d1ec3db51809ca Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 7 Mar 2024 12:26:02 -0800
Subject: [PATCH v25 5/7] Add unicode_strtitle() for Unicode Default Case
Conversion.
This brings the titlecasing implementation out of formatting.c and
into unicode_case.c by accepting an arbitrary word boundary callback.
Simple for now, but can be extended to support the Unicode Default
Case Conversion algorithm with full case mapping.
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 124 ++++++++++++++++-------------
src/common/unicode_case.c | 76 ++++++++++++++++--
src/include/common/unicode_case.h | 5 ++
3 files changed, 142 insertions(+), 63 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 1a578b8a2b..6d5cbe2929 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1920,6 +1920,47 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
return result;
}
+struct WordBoundaryState
+{
+ const char *str;
+ size_t len;
+ size_t offset;
+ bool init;
+ bool prev_alnum;
+};
+
+/*
+ * Simple word boundary iterator that draws boundaries each time the result of
+ * pg_u_isalnum() changes.
+ */
+static size_t
+initcap_wbnext(void *state)
+{
+ struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
+
+ while (wbstate->offset < wbstate->len &&
+ wbstate->str[wbstate->offset] != '\0')
+ {
+ pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ wbstate->offset);
+ bool curr_alnum = pg_u_isalnum(u, true);
+
+ if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
+ {
+ size_t prev_offset = wbstate->offset;
+
+ wbstate->init = true;
+ wbstate->offset += unicode_utf8len(u);
+ wbstate->prev_alnum = curr_alnum;
+ return prev_offset;
+ }
+
+ wbstate->offset += unicode_utf8len(u);
+ }
+
+ return wbstate->len;
+}
+
/*
* collation-aware, wide-character-aware initcap function
*
@@ -1978,69 +2019,42 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
#endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
{
- const unsigned char *src = (unsigned char *) buff;
- unsigned char *dst;
- size_t dstsize = nbytes + 1;
- int srcoff = 0;
- int dstoff = 0;
+ const char *src = buff;
+ size_t srclen = nbytes;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+ struct WordBoundaryState wbstate = {
+ .str = src,
+ .len = srclen,
+ .offset = 0,
+ .init = false,
+ .prev_alnum = false,
+ };
Assert(GetDatabaseEncoding() == PG_UTF8);
- /* Output workspace cannot have more codes than input bytes */
- dst = (unsigned char *) palloc(dstsize);
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
- while (srcoff < nbytes)
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ if (needed + 1 > dstsize)
{
- pg_wchar u1 = utf8_to_unicode(src + srcoff);
- pg_wchar u2;
- int u1len = unicode_utf8len(u1);
- int u2len;
-
- if (wasalnum)
- u2 = unicode_lowercase_simple(u1);
- else
- u2 = unicode_uppercase_simple(u1);
-
- u2len = unicode_utf8len(u2);
-
- wasalnum = pg_u_isalnum(u2, true);
-
- /*
- * If we can't fit the necessary bytes and a terminating NUL,
- * reallocate buffer to the maximum size we might need, and
- * shrink it later.
- */
- if (dstoff + u2len + 1 > dstsize)
- {
- /* Overflow paranoia */
- if ((nbytes + 1) > (INT_MAX / sizeof(pg_wchar)))
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
-
- dstsize = (nbytes + 1) * sizeof(pg_wchar);
- dst = repalloc(dst, dstsize);
- }
+ /* reset iterator */
+ wbstate.offset = 0;
+ wbstate.prev_alnum = false;
- unicode_to_utf8(u2, dst + dstoff);
- srcoff += u1len;
- dstoff += u2len;
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ Assert(needed + 1 == dstsize);
}
- *(dst + dstoff) = '\0';
- dstoff++;
-
- if (dstsize == dstoff)
- {
- result = (char *) dst;
- }
- else
- {
- /* shrink buffer and store result */
- result = palloc(dstoff);
- memcpy(result, dst, dstoff);
- pfree(dst);
- }
+ result = dst;
}
else
{
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 8b77f39e4d..7eb9e89f3f 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -21,8 +21,9 @@
#include "mb/pg_wchar.h"
static const pg_case_map *find_case_map(pg_wchar ucs);
-static size_t convert_case(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, CaseKind casekind);
+static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ CaseKind str_casekind, WordBoundaryNext wbnext,
+ void *wbstate);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -67,7 +68,40 @@ unicode_uppercase_simple(pg_wchar code)
size_t
unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+}
+
+/*
+ * unicode_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * Titlecasing requires knowledge about word boundaries, which is provided by
+ * the callback wbnext. A word boundary is the offset of the start of a word
+ * or the offset of the character immediately following a word.
+ *
+ * The caller is expected to initialize and free the callback state
+ * wbstate. The callback should first return offset 0 for the first boundary;
+ * then the offset of each subsequent word boundary; then the total length of
+ * the string to indicate the final boundary.
+ */
+size_t
+unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ WordBoundaryNext wbnext, void *wbstate)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ wbstate);
}
/*
@@ -89,20 +123,34 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
size_t
unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
}
/*
- * Implement Unicode Default Case Conversion algorithm.
+ * If str_casekind is CaseLower or CaseUpper, map each character in the string
+ * for which a mapping is available.
*
- * Map each character in the string for which a mapping is available.
+ * If str_casekind is CaseTitle, maps characters found on a word boundary to
+ * uppercase and other characters to lowercase.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind casekind)
+ CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
{
+ /* character CaseKind varies while titlecasing */
+ CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
+ size_t boundary = 0;
+
+ Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
+ (str_casekind != CaseTitle && !wbnext && !wbstate));
+
+ if (str_casekind == CaseTitle)
+ {
+ boundary = wbnext(wbstate);
+ Assert(boundary == 0); /* start of text is always a boundary */
+ }
while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
{
@@ -110,9 +158,21 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
int u1len = unicode_utf8len(u1);
const pg_case_map *casemap = find_case_map(u1);
+ if (str_casekind == CaseTitle)
+ {
+ if (srcoff == boundary)
+ {
+ chr_casekind = CaseUpper;
+ boundary = wbnext(wbstate);
+ }
+ else
+ chr_casekind = CaseLower;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
if (casemap)
{
- pg_wchar u2 = casemap->simplemap[casekind];
+ pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
if (result_len + u2len < dstsize)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index df36d8db21..c0c3382e79 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -16,11 +16,16 @@
#include "mb/pg_wchar.h"
+typedef size_t (*WordBoundaryNext) (void *wbstate);
+
pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
+size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
+ ssize_t srclen, WordBoundaryNext wbnext,
+ void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
--
2.34.1
[text/x-patch] v25-0006-Support-Unicode-full-case-mapping-and-conversion.patch (555.7K, ../../[email protected]/7-v25-0006-Support-Unicode-full-case-mapping-and-conversion.patch)
download | inline diff:
From 835d13fdf76a0e39b4a5861968c262d981a5afdf Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 9 Mar 2024 12:55:21 -0800
Subject: [PATCH v25 6/7] Support Unicode full case mapping and conversion.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Generate tables from Unicode SpecialCasing.txt to support more
sophisticated case mapping behavior:
* support case mappings to multiple codepoints, such as "ß"
uppercasing to "SS"
* support conditional case mappings, such as the "final sigma"
* support titlecase variants, such as "dž" uppercasing to "DŽ" but
titlecasing to "Dž"
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 12 +-
src/common/unicode/Makefile | 4 +-
.../unicode/generate-unicode_case_table.pl | 161 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_case.c | 185 +-
src/include/common/unicode_case.h | 8 +-
src/include/common/unicode_case_table.h | 6094 +++++++++--------
7 files changed, 3481 insertions(+), 2987 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 6d5cbe2929..97ccf23583 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,13 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1842,13 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -2038,7 +2038,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2049,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index c38ab36b1e..87d7355794 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -30,7 +30,7 @@ update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
@@ -91,4 +91,4 @@ clean:
rm -f $(OBJS) case_test case_test.o category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
index 44b785b861..02da4b682f 100644
--- a/src/common/unicode/generate-unicode_case_table.pl
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -3,7 +3,7 @@
# Generate Unicode character case mappings. Does not include tailoring
# or locale-specific mappings.
#
-# Input: UnicodeData.txt
+# Input: SpecialCasing.txt UnicodeData.txt
# Output: unicode_case_table.h
#
# Copyright (c) 2000-2023, PostgreSQL Global Development Group
@@ -21,6 +21,10 @@ GetOptions('outdir:s' => \$output_path);
my $output_table_file = "$output_path/unicode_case_table.h";
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
my $FH;
my %simple = ();
@@ -51,6 +55,98 @@ while (my $line = <$FH>)
}
close $FH;
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
# Start writing out the output files
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
@@ -63,6 +159,8 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
$num_simple++ unless $code < 0x80;
}
+my $num_special = scalar(keys %special) + 1;
+
print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
@@ -86,6 +184,19 @@ print $OT <<"EOS";
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -94,12 +205,47 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
@@ -114,8 +260,10 @@ for (my $code = 0; $code < 0x80; $code++)
my $lc = ($simple{$code}{Simple_Lowercase} || $code);
my $tc = ($simple{$code}{Simple_Titlecase} || $code);
my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
$code, $lc, $tc, $uc;
}
printf $OT "\n";
@@ -126,9 +274,14 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
next unless $code >= 0x80; # already output above
my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
$code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
- $map->{Simple_Uppercase};
+ $map->{Simple_Uppercase}, $special_case;
}
print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index b9a4181c32..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_case_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
output: ['unicode_case_table.h'],
command: [
perl, files('generate-unicode_case_table.pl'),
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 7eb9e89f3f..ce14c8061d 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -22,8 +22,10 @@
static const pg_case_map *find_case_map(pg_wchar ucs);
static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext,
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -64,11 +66,16 @@ unicode_uppercase_simple(pg_wchar code)
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, full, NULL,
+ NULL);
}
/*
@@ -87,6 +94,13 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
*
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied; use titlecase mapping for the first character;
+ * and perform adjustment to the first Cased character after a word
+ * boundary. If full is false, use only simple mappings; use uppercase mapping
+ * for the first character; and map the first character of each word to
+ * uppercase.
+ *
* Titlecasing requires knowledge about word boundaries, which is provided by
* the callback wbnext. A word boundary is the offset of the start of a word
* or the offset of the character immediately following a word.
@@ -98,9 +112,9 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
*/
size_t
unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- WordBoundaryNext wbnext, void *wbstate)
+ bool full, WordBoundaryNext wbnext, void *wbstate)
{
- return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, full, wbnext,
wbstate);
}
@@ -119,29 +133,42 @@ unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, full, NULL,
+ NULL);
}
/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
* If str_casekind is CaseLower or CaseUpper, map each character in the string
* for which a mapping is available.
*
- * If str_casekind is CaseTitle, maps characters found on a word boundary to
- * uppercase and other characters to lowercase.
+ * If str_casekind is CaseTitle: for each word boundary, "adjust" forward to
+ * the next Cased character and map it to titlecase; then map subsequent
+ * characters to lowercase until the next word boundary.
+ *
+ * Some characters have special mappings, which can map a single codepoint to
+ * multiple codepoints, or depend on conditions.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
+ void *wbstate)
{
/* character CaseKind varies while titlecasing */
CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
size_t boundary = 0;
+ bool adjusting = true;
Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
(str_casekind != CaseTitle && !wbnext && !wbstate));
@@ -156,21 +183,77 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
{
pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
- const pg_case_map *casemap = find_case_map(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+ /*
+ * Titlecasing has two states: adjusting from boundary (initial
+ * state), and lowercasing until the next boundary.
+ */
if (str_casekind == CaseTitle)
{
if (srcoff == boundary)
{
- chr_casekind = CaseUpper;
+ /* reset to initial state and find the next boundary */
+ adjusting = true;
boundary = wbnext(wbstate);
}
+
+ if (adjusting)
+ {
+ if (!full || pg_u_prop_cased(u1))
+ {
+ /* adjustment done: map to titlecase */
+ adjusting = false;
+ chr_casekind = full ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else
+ casemap = NULL; /* no mapping during adjustment */
+ }
else
+ {
chr_casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Note: only a single special mapping per codepoint is currently
+ * supported, though Unicode allows for multiple special mappings for
+ * a single codepoint.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
}
/* perform mapping, update result_len, and write to dst */
- if (casemap)
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[chr_casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
{
pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
@@ -198,6 +281,82 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
return result_len;
}
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
/* find entry in simple case map, if any */
static const pg_case_map *
find_case_map(pg_wchar ucs)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index c0c3382e79..c982815823 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -22,11 +22,11 @@ pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, WordBoundaryNext wbnext,
- void *wbstate);
+ ssize_t srclen, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
index b239f0b3c3..081d4133b1 100644
--- a/src/include/common/unicode_case_table.h
+++ b/src/include/common/unicode_case_table.h
@@ -20,6 +20,19 @@
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -28,2974 +41,3143 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
*/
-static const pg_case_map case_map[2955] =
+static const pg_case_map case_map[3003] =
{
/* begin dense entries for codepoints < 0x80 */
- {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}},
- {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}},
- {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}},
- {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}},
- {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}},
- {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}},
- {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}},
- {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}},
- {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}},
- {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}},
- {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}},
- {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}},
- {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}},
- {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}},
- {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}},
- {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}},
- {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}},
- {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}},
- {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}},
- {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}},
- {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}},
- {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}},
- {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}},
- {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}},
- {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}},
- {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}},
- {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}},
- {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}},
- {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}},
- {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}},
- {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}},
- {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}},
- {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}},
- {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}},
- {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}},
- {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}},
- {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}},
- {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}},
- {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}},
- {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}},
- {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}},
- {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}},
- {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}},
- {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}},
- {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}},
- {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}},
- {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}},
- {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}},
- {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}},
- {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}},
- {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}},
- {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}},
- {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}},
- {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}},
- {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}},
- {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}},
- {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}},
- {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}},
- {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}},
- {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}},
- {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}},
- {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}},
- {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}},
- {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}},
- {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}},
- {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}},
- {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}},
- {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}},
- {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}},
- {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}},
- {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}},
- {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}},
- {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}},
- {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}},
- {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}},
- {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}},
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
/* begin sparse entries for codepoints >= 0x80 */
- {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}},
- {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}},
- {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}},
- {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}},
- {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}},
- {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}},
- {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}},
- {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}},
- {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}},
- {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}},
- {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}},
- {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}},
- {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}},
- {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}},
- {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}},
- {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}},
- {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}},
- {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}},
- {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}},
- {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}},
- {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}},
- {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}},
- {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}},
- {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}},
- {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}},
- {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}},
- {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}},
- {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}},
- {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}},
- {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}},
- {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}},
- {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}},
- {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}},
- {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}},
- {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}},
- {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}},
- {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}},
- {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}},
- {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}},
- {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}},
- {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}},
- {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}},
- {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}},
- {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}},
- {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}},
- {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}},
- {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}},
- {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}},
- {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}},
- {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}},
- {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}},
- {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}},
- {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}},
- {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}},
- {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}},
- {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}},
- {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}},
- {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}},
- {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}},
- {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}},
- {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}},
- {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}},
- {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}},
- {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}},
- {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}},
- {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}},
- {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}},
- {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}},
- {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}},
- {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}},
- {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}},
- {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}},
- {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}},
- {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}},
- {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}},
- {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}},
- {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}},
- {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}},
- {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}},
- {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}},
- {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}},
- {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}},
- {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}},
- {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}},
- {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}},
- {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}},
- {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}},
- {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}},
- {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}},
- {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}},
- {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}},
- {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}},
- {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}},
- {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}},
- {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}},
- {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}},
- {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}},
- {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}},
- {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
- {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
};
--
2.34.1
[text/x-patch] v25-0007-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch (18.6K, ../../[email protected]/8-v25-0007-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch)
download | inline diff:
From 58824763f9a2fadb7692619c4a409e5b9e55a3d5 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 18:15:33 -0800
Subject: [PATCH v25 7/7] Support PG_UNICODE_FAST locale in the builtin
collation provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------ CATVERSION ------
The PG_UNICODE_FAST locale uses code point sort order (fast,
memcmp-based) combined with Unicode character semantics. The character
semantics are based on Unicode full case mapping.
Full case mapping can map a single codepoint to multiple codepoints,
such as "ß" uppercasing to "SS". Additionally, it handles
context-sensitive mappings like the "final sigma", and it uses
titlecase mappings such as "Dž" when titlecasing (rather than plain
uppercase mappings).
Importantly, the uppercasing of "ß" as "SS" is specifically mentioned
by the SQL standard. In Postgres, UCS_BASIC uses plain ASCII semantics
for case mapping and pattern matching, so if we changed it to use the
PG_UNICODE_FAST locale, it would offer better compliance with the
standard. For now, though, do not change the behavior of UCS_BASIC.
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 17 +++
src/backend/regex/regc_pg_locale.c | 11 +-
src/backend/utils/adt/formatting.c | 22 ++-
src/backend/utils/adt/pg_locale.c | 7 +
src/backend/utils/init/postinit.c | 1 +
src/bin/initdb/initdb.c | 6 +-
src/include/catalog/pg_collation.dat | 3 +
src/include/utils/pg_locale.h | 1 +
src/test/regress/expected/collate.utf8.out | 160 +++++++++++++++++++++
src/test/regress/sql/collate.utf8.sql | 60 ++++++++
10 files changed, 277 insertions(+), 11 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 55bbb20dac..fc520138a6 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -886,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_unicode_fast</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. It is only
+ available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>pg_c_utf8</literal></term>
<listitem>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 85f3238eb0..24c5200cef 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -78,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -271,7 +273,10 @@ pg_set_regex_collation(Oid collation)
if (pg_regex_locale)
{
if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = !pg_regex_locale->info.builtin.casemap_full;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
}
@@ -299,7 +304,7 @@ pg_wc_isdigit(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
case PG_REGEX_BUILTIN:
- return pg_u_isdigit(c, true);
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -367,7 +372,7 @@ pg_wc_isalnum(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
case PG_REGEX_BUILTIN:
- return pg_u_isalnum(c, true);
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -546,7 +551,7 @@ pg_wc_ispunct(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
case PG_REGEX_BUILTIN:
- return pg_u_ispunct(c, true);
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 97ccf23583..47601e75ba 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,15 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1842,13 +1844,15 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1927,6 +1931,7 @@ struct WordBoundaryState
size_t offset;
bool init;
bool prev_alnum;
+ bool posix;
};
/*
@@ -1943,7 +1948,7 @@ initcap_wbnext(void *state)
{
pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
- bool curr_alnum = pg_u_isalnum(u, true);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
{
@@ -2030,6 +2035,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
.offset = 0,
.init = false,
.prev_alnum = false,
+ .posix = !mylocale->info.builtin.casemap_full,
};
Assert(GetDatabaseEncoding() == PG_UTF8);
@@ -2038,7 +2044,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2049,7 +2056,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 793984053f..315daed46d 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1596,6 +1596,7 @@ pg_newlocale_from_collation(Oid collid)
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
locstr);
+ result.info.builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
}
else if (collform->collprovider == COLLPROVIDER_LIBC)
{
@@ -1745,6 +1746,8 @@ get_collation_actual_version(char collprovider, const char *collcollate)
return "1.0";
else if (strcmp(collcollate, "C.UTF-8") == 0)
return "1.0";
+ else if (strcmp(collcollate, "PG_UNICODE_FAST") == 0)
+ return "1.0";
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -2529,6 +2532,8 @@ builtin_locale_encoding(const char *locale)
return -1;
if (strcmp(locale, "C.UTF-8") == 0)
return PG_UTF8;
+ if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ return PG_UTF8;
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -2551,6 +2556,8 @@ builtin_validate_locale(int encoding, const char *locale)
canonical_name = "C";
else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
canonical_name = "C.UTF-8";
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ canonical_name = "PG_UNICODE_FAST";
if (!canonical_name)
ereport(ERROR,
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 0805398e24..9a357e3f90 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -432,6 +432,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
default_locale.info.builtin.locale = MemoryContextStrdup(
TopMemoryContext, datlocale);
+ default_locale.info.builtin.casemap_full = (strcmp(datlocale, "PG_UNICODE_FAST") == 0);
}
else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 30e17bd1d1..262a984d04 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2408,6 +2408,8 @@ setlocales(void)
else if (strcmp(datlocale, "C.UTF-8") == 0 ||
strcmp(datlocale, "C.UTF8") == 0)
canonname = "C.UTF-8";
+ else if (strcmp(datlocale, "PG_UNICODE_FAST") == 0)
+ canonname = "PG_UNICODE_FAST";
else
pg_fatal("invalid locale name \"%s\" for builtin provider",
datlocale);
@@ -2704,7 +2706,9 @@ setup_locale_encoding(void)
if (locale_provider == COLLPROVIDER_BUILTIN)
{
- if (strcmp(datlocale, "C.UTF-8") == 0 && encodingid != PG_UTF8)
+ if ((strcmp(datlocale, "C.UTF-8") == 0 ||
+ strcmp(datlocale, "PG_UNICODE_FAST") == 0) &&
+ encodingid != PG_UTF8)
pg_fatal("builtin provider locale \"%s\" requires encoding \"%s\"",
datlocale, "UTF-8");
}
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 083b0cdcca..579bbbc8b7 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -33,5 +33,8 @@
{ oid => '811', descr => 'sorts by Unicode code point; Unicode and POSIX character semantics',
collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
colllocale => 'C.UTF-8' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST' },
]
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 205aa20067..03890000db 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -79,6 +79,7 @@ struct pg_locale_struct
struct
{
const char *locale;
+ bool casemap_full;
} builtin;
locale_t lt;
#ifdef USE_ICU
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index eff0ef21ac..63327a8fdd 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -134,3 +134,163 @@ SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
t
(1 row)
+--
+-- Test PG_UNICODE_FAST
+--
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+ERROR: invalid locale name "unicode" for builtin provider
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123Abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_unicode_fast;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index 1f5f9ef491..c63928d38e 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -65,3 +65,63 @@ SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+
+--
+-- Test PG_UNICODE_FAST
+--
+
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+
+DROP TABLE test_pg_unicode_fast;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-17 21:46 ` Tom Lane <[email protected]>
2024-03-18 17:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
1 sibling, 1 reply; 94+ messages in thread
From: Tom Lane @ 2024-03-17 21:46 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
Jeff Davis <[email protected]> writes:
> New series attached.
Coverity thinks there's something wrong with builtin_validate_locale,
and as far as I can tell it's right: the last ereport is unreachable,
because required_encoding is never changed from its initial -1 value.
It looks like there's a chunk of logic missing there, or else that
the code could be simplified further.
/srv/coverity/git/pgsql-git/postgresql/src/backend/utils/adt/pg_locale.c: 2519 in builtin_validate_locale()
>>> CID 1594398: Control flow issues (DEADCODE)
>>> Execution cannot reach the expression "encoding != required_encoding" inside this statement: "if (required_encoding >= 0 ...".
2519 if (required_encoding >= 0 && encoding != required_encoding)
2520 ereport(ERROR,
2521 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2522 errmsg("encoding \"%s\" does not match locale \"%s\"",
2523 pg_encoding_to_char(encoding), locale)));
regards, tom lane
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
@ 2024-03-18 17:00 ` Jeff Davis <[email protected]>
2024-03-18 22:04 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-18 17:00 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Sun, 2024-03-17 at 17:46 -0400, Tom Lane wrote:
> Jeff Davis <[email protected]> writes:
> > New series attached.
>
> Coverity thinks there's something wrong with builtin_validate_locale,
> and as far as I can tell it's right: the last ereport is unreachable,
> because required_encoding is never changed from its initial -1 value.
> It looks like there's a chunk of logic missing there, or else that
> the code could be simplified further.
Thank you, it was a bit of over-generalization in anticipation of
future patches.
It may be moot soon, but I committed a fix now.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 17:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-18 22:04 ` Tom Lane <[email protected]>
2024-03-18 22:48 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-18 22:54 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
0 siblings, 2 replies; 94+ messages in thread
From: Tom Lane @ 2024-03-18 22:04 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
Jeff Davis <[email protected]> writes:
> It may be moot soon, but I committed a fix now.
Thanks, but it looks like 846311051 introduced a fresh issue.
MSVC is complaining about
[21:37:15.349] c:\cirrus\src\backend\utils\adt\pg_locale.c(2515) : warning C4715: 'builtin_locale_encoding': not all control paths return a value
This is causing all CI jobs to fail the "compiler warnings" check.
Probably the best fix is the traditional
return <something>; /* keep compiler quiet */
but I'm not sure what the best default result is in this function.
regards, tom lane
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 17:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-18 22:04 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
@ 2024-03-18 22:48 ` Jeff Davis <[email protected]>
1 sibling, 0 replies; 94+ messages in thread
From: Jeff Davis @ 2024-03-18 22:48 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Mon, 2024-03-18 at 18:04 -0400, Tom Lane wrote:
> This is causing all CI jobs to fail the "compiler warnings" check.
I did run CI before checkin, and it passed:
https://cirrus-ci.com/build/5382423490330624
If I open up the windows build, I see the warning:
https://cirrus-ci.com/task/5199979044667392
but I didn't happen to check this time.
> Probably the best fix is the traditional
>
> return <something>; /* keep compiler quiet */
>
> but I'm not sure what the best default result is in this function.
In inverted the check so that I didn't have to choose a default.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 17:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-18 22:04 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
@ 2024-03-18 22:54 ` Tom Lane <[email protected]>
2024-03-19 03:38 ` Re: Built-in CTYPE provider Thomas Munro <[email protected]>
1 sibling, 1 reply; 94+ messages in thread
From: Tom Lane @ 2024-03-18 22:54 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
Jeff Davis <[email protected]> writes:
> On Mon, 2024-03-18 at 18:04 -0400, Tom Lane wrote:
>> This is causing all CI jobs to fail the "compiler warnings" check.
> I did run CI before checkin, and it passed:
> https://cirrus-ci.com/build/5382423490330624
Weird, why did it not report with the same level of urgency?
But anyway, thanks for fixing.
regards, tom lane
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 17:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-18 22:04 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 22:54 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
@ 2024-03-19 03:38 ` Thomas Munro <[email protected]>
2024-03-19 04:03 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Thomas Munro @ 2024-03-19 03:38 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Jeff Davis <[email protected]>; Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Tue, Mar 19, 2024 at 11:55 AM Tom Lane <[email protected]> wrote:
> Jeff Davis <[email protected]> writes:
> > On Mon, 2024-03-18 at 18:04 -0400, Tom Lane wrote:
> >> This is causing all CI jobs to fail the "compiler warnings" check.
>
> > I did run CI before checkin, and it passed:
> > https://cirrus-ci.com/build/5382423490330624
>
> Weird, why did it not report with the same level of urgency?
> But anyway, thanks for fixing.
Maybe I misunderstood this exchange but ...
Currently Windows warnings don't make any CI tasks fail ie turn red,
which is why Jeff's run is all green in his personal github repo.
Unlike gcc and clang, and MinGW cross-build warnings which cause the
special "CompilerWarnings" CI task to fail (red). That task is
running on a Linux system so it can't use MSVC. The idea of keeping
it separate from the "main" Linux, FreeBSD, macOS tasks (which use
gcc, clang, clang respectively) was that it's nicer to try to run the
actual tests even if there is a pesky warning, so having it in a
separate task gets you that info without blocking other progress, and
it also tries with and without assertions (a category of warning
hazard, eg unused variables when assertions are off).
But I did teach cfbot to do some extra digging through the logs,
looking for various interesting patterns[1], including non-error
warnings, and if it finds anything interesting it shows a little
clickable ⚠ symbol on the front page.
If there is something like -Werror on MSVC we could turn that on for
the main Windows test, but that might also be a bit annoying. Perhaps
there is another way: we could have it compile and test everything,
allowing warnings, but also then grep the build log afterwards in a
new step that fails if any warnings were there? Then Jeff would have
got a failure in his personal CI run. Or something like that.
[1] https://github.com/macdice/cfbot/blob/master/cfbot_work_queue.py
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 17:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-18 22:04 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 22:54 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-19 03:38 ` Re: Built-in CTYPE provider Thomas Munro <[email protected]>
@ 2024-03-19 04:03 ` Tom Lane <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tom Lane @ 2024-03-19 04:03 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Jeff Davis <[email protected]>; Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
Thomas Munro <[email protected]> writes:
> On Tue, Mar 19, 2024 at 11:55 AM Tom Lane <[email protected]> wrote:
>>>> This is causing all CI jobs to fail the "compiler warnings" check.
>>> I did run CI before checkin, and it passed:
> Maybe I misunderstood this exchange but ...
> Currently Windows warnings don't make any CI tasks fail ie turn red,
> which is why Jeff's run is all green in his personal github repo.
> ...
> But I did teach cfbot to do some extra digging through the logs,
Ah. What I should have said was "it's causing cfbot to complain
about every patch".
Seems like the divergence in the pass criterion is not such a
great idea.
regards, tom lane
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-19 12:41 ` Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
1 sibling, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-19 12:41 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
* v25-0001-Address-more-review-comments-on-commit-2d819a08a.patch
This was committed.
* v25-0002-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch
Looks ok.
* v25-0003-Inline-basic-UTF-8-functions.patch
ok
* v25-0004-Use-version-for-builtin-collations.patch
Not sure about the version format "1.0", which implies some sort of
major/minor or component-based system. I would just use "1".
* v25-0005-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch
* v25-0006-Support-Unicode-full-case-mapping-and-conversion.patch
* v25-0007-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch
0005 and 0006 don't contain any test cases. So I guess they are really
only usable via 0007. Is that understanding correct?
Btw., tested initcap() on Oracle:
select initcap('džudo') from dual;
(which uses the precomposed U+01F3) and the result is
DŽudo
(with the precomposed uppercase character). So that matches the
behavior proposed in your 0002 patch.
Are there any test cases that illustrate the word boundary changes in
patch 0005? It might be useful to test those against Oracle as well.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-03-21 00:13 ` Jeff Davis <[email protected]>
2024-03-22 14:51 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-24 11:00 ` Re: Built-in CTYPE provider Alexander Lakhin <[email protected]>
2024-03-26 07:04 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-27 15:53 ` Re: Built-in CTYPE provider Daniel Verite <[email protected]>
2024-06-29 22:08 ` Re: Built-in CTYPE provider Noah Misch <[email protected]>
0 siblings, 5 replies; 94+ messages in thread
From: Jeff Davis @ 2024-03-21 00:13 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Tue, 2024-03-19 at 13:41 +0100, Peter Eisentraut wrote:
> * v25-0002-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch
>
> Looks ok.
Committed.
> * v25-0003-Inline-basic-UTF-8-functions.patch
Committed.
> * v25-0004-Use-version-for-builtin-collations.patch
>
> Not sure about the version format "1.0", which implies some sort of
> major/minor or component-based system. I would just use "1".
The v26 patch was not quite complete, so I didn't commit it yet.
Attached v27-0001 and 0002.
0002 is necessary because otherwise lc_collate_is_c() short-circuits
the version check in pg_newlocale_from_collation(). With 0002, the code
is simpler and all paths go through pg_newlocale_from_collation(), and
the version check happens even when lc_collate_is_c().
But perhaps there was a reason the code was the way it was, so
submitting for review in case I missed something.
> 0005 and 0006 don't contain any test cases. So I guess they are
> really
> only usable via 0007. Is that understanding correct?
0005 is not a functional change, it's just a refactoring to use a
callback, which is preparation for 0007.
> Are there any test cases that illustrate the word boundary changes in
> patch 0005? It might be useful to test those against Oracle as well.
The tests include initcap('123abc') which is '123abc' in the PG_C_UTF8
collation vs '123Abc' in PG_UNICODE_FAST.
The reason for the latter behavior is that the Unicode Default Case
Conversion algorithm for toTitlecase() advances to the next Cased
character before mapping to titlecase, and digits are not Cased. ICU
has a configurable adjustment, and defaults in a way that produces
'123abc'.
New rebased series attached.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v27-0001-Use-version-for-builtin-collations.patch (2.7K, ../../[email protected]/2-v27-0001-Use-version-for-builtin-collations.patch)
download | inline diff:
From 98d894e141cbf0701714efad3afdbc98516b878f Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 14 Mar 2024 12:07:45 -0700
Subject: [PATCH v27 1/5] Use version for builtin collations.
------ CATVERSION ------
Even though we don't expect any changes to memcmp() semantics, it's
plausible that the surrounding optimizations (including future
optimizations that don't exist today) may have bugs.
Given that the version field already exists, there's little reason not
to use it. Suggestion from Peter Eisentraut.
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/pg_locale.c | 15 +++++++++++++--
src/include/catalog/pg_collation.dat | 4 ++--
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index e10d328fc3..aa40921d7d 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1732,13 +1732,24 @@ get_collation_actual_version(char collprovider, const char *collcollate)
/*
* The only two supported locales (C and C.UTF-8) are both based on memcmp
- * and are not expected to change.
+ * and are not expected to change, but track the version anyway.
*
* Note that the character semantics may change for some locales, but the
* collation version only tracks changes to sort order.
*/
if (collprovider == COLLPROVIDER_BUILTIN)
- return NULL;
+ {
+ Assert(collcollate != NULL);
+ if (strcmp(collcollate, "C") == 0)
+ return "1";
+ else if (strcmp(collcollate, "C.UTF-8") == 0)
+ return "1";
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("invalid locale name \"%s\" for builtin provider",
+ collcollate)));
+ }
#ifdef USE_ICU
if (collprovider == COLLPROVIDER_ICU)
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index 083b0cdcca..dcf554bbd5 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -25,13 +25,13 @@
collcollate => 'POSIX', collctype => 'POSIX' },
{ oid => '962', descr => 'sorts by Unicode code point, C character semantics',
collname => 'ucs_basic', collprovider => 'b', collencoding => '6',
- colllocale => 'C' },
+ colllocale => 'C', collversion => '1' },
{ oid => '963',
descr => 'sorts using the Unicode Collation Algorithm with default settings',
collname => 'unicode', collprovider => 'i', collencoding => '-1',
colllocale => 'und' },
{ oid => '811', descr => 'sorts by Unicode code point; Unicode and POSIX character semantics',
collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
- colllocale => 'C.UTF-8' },
+ colllocale => 'C.UTF-8', collversion => '1' },
]
--
2.34.1
[text/x-patch] v27-0002-Simplify-lookup_collation_cache.patch (5.6K, ../../[email protected]/3-v27-0002-Simplify-lookup_collation_cache.patch)
download | inline diff:
From 75ec4838af6618bdc408045369486497125d5aa7 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 20 Mar 2024 17:00:13 -0700
Subject: [PATCH v27 2/5] Simplify lookup_collation_cache.
Attach flags 'collate_is_c' and 'ctype_is_c' to pg_locale_t instead of
the collation cache entry. pg_newlocale_from_collation() already has
the catalog entry, so it's easy to set the flags from there, instead.
---
src/backend/utils/adt/pg_locale.c | 77 ++++++-------------------------
src/include/utils/pg_locale.h | 2 +
2 files changed, 16 insertions(+), 63 deletions(-)
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index aa40921d7d..999d78d01c 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -125,9 +125,6 @@ static bool CurrentLCTimeValid = false;
typedef struct
{
Oid collid; /* hash key: pg_collation OID */
- bool collate_is_c; /* is collation's LC_COLLATE C? */
- bool ctype_is_c; /* is collation's LC_CTYPE C? */
- bool flags_valid; /* true if above flags are valid */
pg_locale_t locale; /* locale_t struct, or 0 if not valid */
} collation_cache_entry;
@@ -1227,7 +1224,7 @@ IsoLocaleName(const char *winlocname)
*/
static collation_cache_entry *
-lookup_collation_cache(Oid collation, bool set_flags)
+lookup_collation_cache(Oid collation)
{
collation_cache_entry *cache_entry;
bool found;
@@ -1248,63 +1245,7 @@ lookup_collation_cache(Oid collation, bool set_flags)
cache_entry = hash_search(collation_cache, &collation, HASH_ENTER, &found);
if (!found)
- {
- /*
- * Make sure cache entry is marked invalid, in case we fail before
- * setting things.
- */
- cache_entry->flags_valid = false;
cache_entry->locale = 0;
- }
-
- if (set_flags && !cache_entry->flags_valid)
- {
- /* Attempt to set the flags */
- HeapTuple tp;
- Form_pg_collation collform;
-
- tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collation));
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "cache lookup failed for collation %u", collation);
- collform = (Form_pg_collation) GETSTRUCT(tp);
-
- if (collform->collprovider == COLLPROVIDER_BUILTIN)
- {
- Datum datum;
- const char *colllocale;
-
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
- colllocale = TextDatumGetCString(datum);
-
- cache_entry->collate_is_c = true;
- cache_entry->ctype_is_c = (strcmp(colllocale, "C") == 0);
- }
- else if (collform->collprovider == COLLPROVIDER_LIBC)
- {
- Datum datum;
- const char *collcollate;
- const char *collctype;
-
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collcollate);
- collcollate = TextDatumGetCString(datum);
- datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
- collctype = TextDatumGetCString(datum);
-
- cache_entry->collate_is_c = ((strcmp(collcollate, "C") == 0) ||
- (strcmp(collcollate, "POSIX") == 0));
- cache_entry->ctype_is_c = ((strcmp(collctype, "C") == 0) ||
- (strcmp(collctype, "POSIX") == 0));
- }
- else
- {
- cache_entry->collate_is_c = false;
- cache_entry->ctype_is_c = false;
- }
-
- cache_entry->flags_valid = true;
-
- ReleaseSysCache(tp);
- }
return cache_entry;
}
@@ -1374,7 +1315,7 @@ lc_collate_is_c(Oid collation)
/*
* Otherwise, we have to consult pg_collation, but we cache that.
*/
- return (lookup_collation_cache(collation, true))->collate_is_c;
+ return pg_newlocale_from_collation(collation)->collate_is_c;
}
/*
@@ -1440,7 +1381,7 @@ lc_ctype_is_c(Oid collation)
/*
* Otherwise, we have to consult pg_collation, but we cache that.
*/
- return (lookup_collation_cache(collation, true))->ctype_is_c;
+ return pg_newlocale_from_collation(collation)->ctype_is_c;
}
struct pg_locale_struct default_locale;
@@ -1563,7 +1504,7 @@ pg_newlocale_from_collation(Oid collid)
return &default_locale;
}
- cache_entry = lookup_collation_cache(collid, false);
+ cache_entry = lookup_collation_cache(collid);
if (cache_entry->locale == 0)
{
@@ -1592,6 +1533,8 @@ pg_newlocale_from_collation(Oid collid)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
locstr = TextDatumGetCString(datum);
+ result.collate_is_c = true;
+ result.ctype_is_c = (strcmp(locstr, "C") == 0);
builtin_validate_locale(GetDatabaseEncoding(), locstr);
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
@@ -1608,6 +1551,11 @@ pg_newlocale_from_collation(Oid collid)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_collctype);
collctype = TextDatumGetCString(datum);
+ result.collate_is_c = ((strcmp(collcollate, "C") == 0) ||
+ (strcmp(collcollate, "POSIX") == 0));
+ result.ctype_is_c = ((strcmp(collctype, "C") == 0) ||
+ (strcmp(collctype, "POSIX") == 0));
+
if (strcmp(collcollate, collctype) == 0)
{
/* Normal case where they're the same */
@@ -1658,6 +1606,9 @@ pg_newlocale_from_collation(Oid collid)
datum = SysCacheGetAttrNotNull(COLLOID, tp, Anum_pg_collation_colllocale);
iculocstr = TextDatumGetCString(datum);
+ result.collate_is_c = false;
+ result.ctype_is_c = false;
+
datum = SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
if (!isnull)
icurules = TextDatumGetCString(datum);
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 205aa20067..41659cdbbd 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -74,6 +74,8 @@ struct pg_locale_struct
{
char provider;
bool deterministic;
+ bool collate_is_c;
+ bool ctype_is_c;
union
{
struct
--
2.34.1
[text/x-patch] v27-0003-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch (9.2K, ../../[email protected]/4-v27-0003-Add-unicode_strtitle-for-Unicode-Default-Case-Co.patch)
download | inline diff:
From 43e0f028aebd29a0b5a69fcb82282d53d7d3aea4 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 7 Mar 2024 12:26:02 -0800
Subject: [PATCH v27 3/5] Add unicode_strtitle() for Unicode Default Case
Conversion.
This brings the titlecasing implementation out of formatting.c and
into unicode_case.c by accepting an arbitrary word boundary callback.
Simple for now, but can be extended to support the Unicode Default
Case Conversion algorithm with full case mapping.
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 109 ++++++++++++++++++-----------
src/common/unicode_case.c | 76 +++++++++++++++++---
src/include/common/unicode_case.h | 5 ++
3 files changed, 141 insertions(+), 49 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 8160d78ec6..1e0fbb43fb 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1922,6 +1922,47 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
return result;
}
+struct WordBoundaryState
+{
+ const char *str;
+ size_t len;
+ size_t offset;
+ bool init;
+ bool prev_alnum;
+};
+
+/*
+ * Simple word boundary iterator that draws boundaries each time the result of
+ * pg_u_isalnum() changes.
+ */
+static size_t
+initcap_wbnext(void *state)
+{
+ struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
+
+ while (wbstate->offset < wbstate->len &&
+ wbstate->str[wbstate->offset] != '\0')
+ {
+ pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ wbstate->offset);
+ bool curr_alnum = pg_u_isalnum(u, true);
+
+ if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
+ {
+ size_t prev_offset = wbstate->offset;
+
+ wbstate->init = true;
+ wbstate->offset += unicode_utf8len(u);
+ wbstate->prev_alnum = curr_alnum;
+ return prev_offset;
+ }
+
+ wbstate->offset += unicode_utf8len(u);
+ }
+
+ return wbstate->len;
+}
+
/*
* collation-aware, wide-character-aware initcap function
*
@@ -1980,56 +2021,42 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
#endif
if (mylocale && mylocale->provider == COLLPROVIDER_BUILTIN)
{
- const unsigned char *src = (unsigned char *) buff;
+ const char *src = buff;
size_t srclen = nbytes;
- unsigned char *dst;
- size_t dstsize;
- int srcoff = 0;
- int dstoff = 0;
+ size_t dstsize = srclen + 1;
+ char *dst = palloc(dstsize);
+ size_t needed;
+ struct WordBoundaryState wbstate = {
+ .str = src,
+ .len = srclen,
+ .offset = 0,
+ .init = false,
+ .prev_alnum = false,
+ };
Assert(GetDatabaseEncoding() == PG_UTF8);
- /* overflow paranoia */
- if ((srclen + 1) > (INT_MAX / MAX_MULTIBYTE_CHAR_LEN))
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
-
- /* result is at most srclen codepoints plus terminating NUL */
- dstsize = srclen * MAX_MULTIBYTE_CHAR_LEN + 1;
- dst = (unsigned char *) palloc(dstsize);
+ /* first try buffer of equal size */
+ dstsize = srclen + 1;
+ result = palloc(dstsize);
- while (srcoff < nbytes)
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ if (needed + 1 > dstsize)
{
- pg_wchar u1 = utf8_to_unicode(src + srcoff);
- pg_wchar u2;
- int u1len = unicode_utf8len(u1);
- int u2len;
-
- if (wasalnum)
- u2 = unicode_lowercase_simple(u1);
- else
- u2 = unicode_uppercase_simple(u1);
-
- u2len = unicode_utf8len(u2);
+ /* reset iterator */
+ wbstate.offset = 0;
+ wbstate.prev_alnum = false;
- Assert(dstoff + u2len + 1 <= dstsize);
-
- wasalnum = pg_u_isalnum(u2, true);
-
- unicode_to_utf8(u2, dst + dstoff);
- srcoff += u1len;
- dstoff += u2len;
+ /* grow buffer if needed and retry */
+ dstsize = needed + 1;
+ dst = repalloc(dst, dstsize);
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ initcap_wbnext, &wbstate);
+ Assert(needed + 1 == dstsize);
}
- Assert(dstoff + 1 <= dstsize);
- *(dst + dstoff) = '\0';
- dstoff++;
-
- /* allocate result buffer of the right size and free workspace */
- result = palloc(dstoff);
- memcpy(result, dst, dstoff);
- pfree(dst);
+ result = dst;
}
else
{
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 8b77f39e4d..7eb9e89f3f 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -21,8 +21,9 @@
#include "mb/pg_wchar.h"
static const pg_case_map *find_case_map(pg_wchar ucs);
-static size_t convert_case(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, CaseKind casekind);
+static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ CaseKind str_casekind, WordBoundaryNext wbnext,
+ void *wbstate);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -67,7 +68,40 @@ unicode_uppercase_simple(pg_wchar code)
size_t
unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+}
+
+/*
+ * unicode_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not including
+ * terminating NUL).
+ *
+ * String src must be encoded in UTF-8. If srclen < 0, src must be
+ * NUL-terminated.
+ *
+ * Result string is stored in dst, truncating if larger than dstsize. If
+ * dstsize is greater than the result length, dst will be NUL-terminated;
+ * otherwise not.
+ *
+ * If dstsize is zero, dst may be NULL. This is useful for calculating the
+ * required buffer size before allocating.
+ *
+ * Titlecasing requires knowledge about word boundaries, which is provided by
+ * the callback wbnext. A word boundary is the offset of the start of a word
+ * or the offset of the character immediately following a word.
+ *
+ * The caller is expected to initialize and free the callback state
+ * wbstate. The callback should first return offset 0 for the first boundary;
+ * then the offset of each subsequent word boundary; then the total length of
+ * the string to indicate the final boundary.
+ */
+size_t
+unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ WordBoundaryNext wbnext, void *wbstate)
+{
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ wbstate);
}
/*
@@ -89,20 +123,34 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
size_t
unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
}
/*
- * Implement Unicode Default Case Conversion algorithm.
+ * If str_casekind is CaseLower or CaseUpper, map each character in the string
+ * for which a mapping is available.
*
- * Map each character in the string for which a mapping is available.
+ * If str_casekind is CaseTitle, maps characters found on a word boundary to
+ * uppercase and other characters to lowercase.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind casekind)
+ CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
{
+ /* character CaseKind varies while titlecasing */
+ CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
+ size_t boundary = 0;
+
+ Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
+ (str_casekind != CaseTitle && !wbnext && !wbstate));
+
+ if (str_casekind == CaseTitle)
+ {
+ boundary = wbnext(wbstate);
+ Assert(boundary == 0); /* start of text is always a boundary */
+ }
while (src[srcoff] != '\0' && (srclen < 0 || srcoff < srclen))
{
@@ -110,9 +158,21 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
int u1len = unicode_utf8len(u1);
const pg_case_map *casemap = find_case_map(u1);
+ if (str_casekind == CaseTitle)
+ {
+ if (srcoff == boundary)
+ {
+ chr_casekind = CaseUpper;
+ boundary = wbnext(wbstate);
+ }
+ else
+ chr_casekind = CaseLower;
+ }
+
+ /* perform mapping, update result_len, and write to dst */
if (casemap)
{
- pg_wchar u2 = casemap->simplemap[casekind];
+ pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
if (result_len + u2len < dstsize)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index df36d8db21..c0c3382e79 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -16,11 +16,16 @@
#include "mb/pg_wchar.h"
+typedef size_t (*WordBoundaryNext) (void *wbstate);
+
pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
+size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
+ ssize_t srclen, WordBoundaryNext wbnext,
+ void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
ssize_t srclen);
--
2.34.1
[text/x-patch] v27-0004-Support-Unicode-full-case-mapping-and-conversion.patch (555.7K, ../../[email protected]/5-v27-0004-Support-Unicode-full-case-mapping-and-conversion.patch)
download | inline diff:
From 60775d01ecd475569dd0bde4c69d6070c0800748 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 9 Mar 2024 12:55:21 -0800
Subject: [PATCH v27 4/5] Support Unicode full case mapping and conversion.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Generate tables from Unicode SpecialCasing.txt to support more
sophisticated case mapping behavior:
* support case mappings to multiple codepoints, such as "ß"
uppercasing to "SS"
* support conditional case mappings, such as the "final sigma"
* support titlecase variants, such as "dž" uppercasing to "DŽ" but
titlecasing to "Dž"
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 12 +-
src/common/unicode/Makefile | 4 +-
.../unicode/generate-unicode_case_table.pl | 161 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_case.c | 185 +-
src/include/common/unicode_case.h | 8 +-
src/include/common/unicode_case_table.h | 6094 +++++++++--------
7 files changed, 3481 insertions(+), 2987 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 1e0fbb43fb..482513867f 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,13 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -1843,13 +1843,13 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -2040,7 +2040,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2051,7 +2051,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index c38ab36b1e..87d7355794 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -30,7 +30,7 @@ update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
@@ -91,4 +91,4 @@ clean:
rm -f $(OBJS) case_test case_test.o category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
index 44b785b861..02da4b682f 100644
--- a/src/common/unicode/generate-unicode_case_table.pl
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -3,7 +3,7 @@
# Generate Unicode character case mappings. Does not include tailoring
# or locale-specific mappings.
#
-# Input: UnicodeData.txt
+# Input: SpecialCasing.txt UnicodeData.txt
# Output: unicode_case_table.h
#
# Copyright (c) 2000-2023, PostgreSQL Global Development Group
@@ -21,6 +21,10 @@ GetOptions('outdir:s' => \$output_path);
my $output_table_file = "$output_path/unicode_case_table.h";
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
my $FH;
my %simple = ();
@@ -51,6 +55,98 @@ while (my $line = <$FH>)
}
close $FH;
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
# Start writing out the output files
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
@@ -63,6 +159,8 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
$num_simple++ unless $code < 0x80;
}
+my $num_special = scalar(keys %special) + 1;
+
print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
@@ -86,6 +184,19 @@ print $OT <<"EOS";
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -94,12 +205,47 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
@@ -114,8 +260,10 @@ for (my $code = 0; $code < 0x80; $code++)
my $lc = ($simple{$code}{Simple_Lowercase} || $code);
my $tc = ($simple{$code}{Simple_Titlecase} || $code);
my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
$code, $lc, $tc, $uc;
}
printf $OT "\n";
@@ -126,9 +274,14 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
next unless $code >= 0x80; # already output above
my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
$code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
- $map->{Simple_Uppercase};
+ $map->{Simple_Uppercase}, $special_case;
}
print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index b9a4181c32..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_case_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
output: ['unicode_case_table.h'],
command: [
perl, files('generate-unicode_case_table.pl'),
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 7eb9e89f3f..ce14c8061d 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -22,8 +22,10 @@
static const pg_case_map *find_case_map(pg_wchar ucs);
static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext,
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -64,11 +66,16 @@ unicode_uppercase_simple(pg_wchar code)
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, full, NULL,
+ NULL);
}
/*
@@ -87,6 +94,13 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
*
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied; use titlecase mapping for the first character;
+ * and perform adjustment to the first Cased character after a word
+ * boundary. If full is false, use only simple mappings; use uppercase mapping
+ * for the first character; and map the first character of each word to
+ * uppercase.
+ *
* Titlecasing requires knowledge about word boundaries, which is provided by
* the callback wbnext. A word boundary is the offset of the start of a word
* or the offset of the character immediately following a word.
@@ -98,9 +112,9 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
*/
size_t
unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- WordBoundaryNext wbnext, void *wbstate)
+ bool full, WordBoundaryNext wbnext, void *wbstate)
{
- return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, full, wbnext,
wbstate);
}
@@ -119,29 +133,42 @@ unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, full, NULL,
+ NULL);
}
/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
* If str_casekind is CaseLower or CaseUpper, map each character in the string
* for which a mapping is available.
*
- * If str_casekind is CaseTitle, maps characters found on a word boundary to
- * uppercase and other characters to lowercase.
+ * If str_casekind is CaseTitle: for each word boundary, "adjust" forward to
+ * the next Cased character and map it to titlecase; then map subsequent
+ * characters to lowercase until the next word boundary.
+ *
+ * Some characters have special mappings, which can map a single codepoint to
+ * multiple codepoints, or depend on conditions.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
+ void *wbstate)
{
/* character CaseKind varies while titlecasing */
CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
size_t boundary = 0;
+ bool adjusting = true;
Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
(str_casekind != CaseTitle && !wbnext && !wbstate));
@@ -156,21 +183,77 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
{
pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
- const pg_case_map *casemap = find_case_map(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+ /*
+ * Titlecasing has two states: adjusting from boundary (initial
+ * state), and lowercasing until the next boundary.
+ */
if (str_casekind == CaseTitle)
{
if (srcoff == boundary)
{
- chr_casekind = CaseUpper;
+ /* reset to initial state and find the next boundary */
+ adjusting = true;
boundary = wbnext(wbstate);
}
+
+ if (adjusting)
+ {
+ if (!full || pg_u_prop_cased(u1))
+ {
+ /* adjustment done: map to titlecase */
+ adjusting = false;
+ chr_casekind = full ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else
+ casemap = NULL; /* no mapping during adjustment */
+ }
else
+ {
chr_casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Note: only a single special mapping per codepoint is currently
+ * supported, though Unicode allows for multiple special mappings for
+ * a single codepoint.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
}
/* perform mapping, update result_len, and write to dst */
- if (casemap)
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[chr_casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len < dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
{
pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
@@ -198,6 +281,82 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
return result_len;
}
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
/* find entry in simple case map, if any */
static const pg_case_map *
find_case_map(pg_wchar ucs)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index c0c3382e79..c982815823 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -22,11 +22,11 @@ pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, WordBoundaryNext wbnext,
- void *wbstate);
+ ssize_t srclen, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
index b239f0b3c3..081d4133b1 100644
--- a/src/include/common/unicode_case_table.h
+++ b/src/include/common/unicode_case_table.h
@@ -20,6 +20,19 @@
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -28,2974 +41,3143 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
*/
-static const pg_case_map case_map[2955] =
+static const pg_case_map case_map[3003] =
{
/* begin dense entries for codepoints < 0x80 */
- {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}},
- {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}},
- {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}},
- {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}},
- {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}},
- {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}},
- {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}},
- {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}},
- {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}},
- {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}},
- {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}},
- {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}},
- {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}},
- {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}},
- {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}},
- {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}},
- {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}},
- {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}},
- {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}},
- {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}},
- {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}},
- {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}},
- {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}},
- {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}},
- {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}},
- {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}},
- {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}},
- {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}},
- {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}},
- {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}},
- {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}},
- {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}},
- {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}},
- {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}},
- {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}},
- {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}},
- {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}},
- {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}},
- {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}},
- {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}},
- {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}},
- {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}},
- {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}},
- {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}},
- {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}},
- {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}},
- {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}},
- {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}},
- {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}},
- {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}},
- {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}},
- {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}},
- {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}},
- {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}},
- {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}},
- {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}},
- {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}},
- {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}},
- {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}},
- {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}},
- {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}},
- {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}},
- {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}},
- {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}},
- {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}},
- {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}},
- {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}},
- {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}},
- {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}},
- {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}},
- {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}},
- {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}},
- {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}},
- {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}},
- {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}},
- {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}},
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
/* begin sparse entries for codepoints >= 0x80 */
- {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}},
- {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}},
- {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}},
- {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}},
- {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}},
- {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}},
- {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}},
- {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}},
- {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}},
- {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}},
- {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}},
- {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}},
- {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}},
- {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}},
- {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}},
- {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}},
- {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}},
- {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}},
- {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}},
- {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}},
- {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}},
- {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}},
- {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}},
- {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}},
- {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}},
- {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}},
- {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}},
- {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}},
- {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}},
- {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}},
- {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}},
- {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}},
- {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}},
- {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}},
- {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}},
- {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}},
- {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}},
- {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}},
- {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}},
- {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}},
- {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}},
- {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}},
- {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}},
- {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}},
- {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}},
- {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}},
- {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}},
- {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}},
- {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}},
- {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}},
- {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}},
- {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}},
- {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}},
- {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}},
- {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}},
- {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}},
- {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}},
- {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}},
- {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}},
- {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}},
- {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}},
- {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}},
- {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}},
- {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}},
- {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}},
- {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}},
- {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}},
- {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}},
- {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}},
- {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}},
- {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}},
- {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}},
- {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}},
- {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}},
- {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}},
- {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}},
- {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}},
- {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}},
- {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}},
- {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}},
- {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}},
- {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}},
- {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}},
- {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}},
- {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}},
- {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}},
- {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}},
- {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}},
- {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}},
- {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}},
- {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}},
- {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}},
- {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}},
- {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}},
- {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}},
- {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}},
- {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}},
- {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}},
- {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
- {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
};
--
2.34.1
[text/x-patch] v27-0005-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch (21.4K, ../../[email protected]/6-v27-0005-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch)
download | inline diff:
From 5cb329bdad34d3c32d0558a20f80c6bc8a13f0b4 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 18:15:33 -0800
Subject: [PATCH v27 5/5] Support PG_UNICODE_FAST locale in the builtin
collation provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------ CATVERSION ------
The PG_UNICODE_FAST locale uses code point sort order (fast,
memcmp-based) combined with Unicode character semantics. The character
semantics are based on Unicode full case mapping.
Full case mapping can map a single codepoint to multiple codepoints,
such as "ß" uppercasing to "SS". Additionally, it handles
context-sensitive mappings like the "final sigma", and it uses
titlecase mappings such as "Dž" when titlecasing (rather than plain
uppercase mappings).
Importantly, the uppercasing of "ß" as "SS" is specifically mentioned
by the SQL standard. In Postgres, UCS_BASIC uses plain ASCII semantics
for case mapping and pattern matching, so if we changed it to use the
PG_UNICODE_FAST locale, it would offer better compliance with the
standard. For now, though, do not change the behavior of UCS_BASIC.
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 17 +++
doc/src/sgml/ref/create_collation.sgml | 3 +-
doc/src/sgml/ref/create_database.sgml | 6 +-
doc/src/sgml/ref/initdb.sgml | 4 +-
src/backend/regex/regc_pg_locale.c | 11 +-
src/backend/utils/adt/formatting.c | 22 ++-
src/backend/utils/adt/pg_locale.c | 10 +-
src/backend/utils/init/postinit.c | 1 +
src/bin/initdb/initdb.c | 6 +-
src/include/catalog/pg_collation.dat | 3 +
src/include/utils/pg_locale.h | 1 +
src/test/regress/expected/collate.utf8.out | 160 +++++++++++++++++++++
src/test/regress/sql/collate.utf8.sql | 60 ++++++++
13 files changed, 287 insertions(+), 17 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 55bbb20dac..fc520138a6 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -886,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_unicode_fast</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. It is only
+ available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>pg_c_utf8</literal></term>
<listitem>
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 85f18cbbe5..4c03e25d02 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -99,7 +99,8 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<para>
If <replaceable>provider</replaceable> is <literal>builtin</literal>,
then <replaceable>locale</replaceable> must be specified and set to
- either <literal>C</literal> or <literal>C.UTF-8</literal>.
+ either <literal>C</literal>, <literal>C.UTF-8</literal> or
+ <literal>PG_UNICODE_FAST</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 7653cb902e..a4b052ba08 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -168,7 +168,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
If <xref linkend="create-database-locale-provider"/> is
<literal>builtin</literal>, then <replaceable>locale</replaceable> or
<replaceable>builtin_locale</replaceable> must be specified and set to
- either <literal>C</literal> or <literal>C.UTF-8</literal>.
+ either <literal>C</literal>, <literal>C.UTF-8</literal>, or
+ <literal>PG_UNICODE_FAST</literal>.
</para>
<tip>
<para>
@@ -233,7 +234,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
</para>
<para>
The locales available for the <literal>builtin</literal> provider are
- <literal>C</literal> and <literal>C.UTF-8</literal>.
+ <literal>C</literal>, <literal>C.UTF-8</literal> and
+ <literal>PG_UNICODE_FAST</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index 377c3cb20a..e9664eddb8 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -289,8 +289,8 @@ PostgreSQL documentation
<para>
If <option>--locale-provider</option> is <literal>builtin</literal>,
<option>--locale</option> or <option>--builtin-locale</option> must be
- specified and set to <literal>C</literal> or
- <literal>C.UTF-8</literal>.
+ specified and set to <literal>C</literal>, <literal>C.UTF-8</literal>
+ or <literal>PG_UNICODE_FAST</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 85f3238eb0..24c5200cef 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -78,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -271,7 +273,10 @@ pg_set_regex_collation(Oid collation)
if (pg_regex_locale)
{
if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = !pg_regex_locale->info.builtin.casemap_full;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
}
@@ -299,7 +304,7 @@ pg_wc_isdigit(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
case PG_REGEX_BUILTIN:
- return pg_u_isdigit(c, true);
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -367,7 +372,7 @@ pg_wc_isalnum(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
case PG_REGEX_BUILTIN:
- return pg_u_isalnum(c, true);
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -546,7 +551,7 @@ pg_wc_ispunct(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
case PG_REGEX_BUILTIN:
- return pg_u_ispunct(c, true);
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 482513867f..36b6d77bf3 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,15 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1843,13 +1845,15 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1929,6 +1933,7 @@ struct WordBoundaryState
size_t offset;
bool init;
bool prev_alnum;
+ bool posix;
};
/*
@@ -1945,7 +1950,7 @@ initcap_wbnext(void *state)
{
pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
- bool curr_alnum = pg_u_isalnum(u, true);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
{
@@ -2032,6 +2037,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
.offset = 0,
.init = false,
.prev_alnum = false,
+ .posix = !mylocale->info.builtin.casemap_full,
};
Assert(GetDatabaseEncoding() == PG_UTF8);
@@ -2040,7 +2046,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
result = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2051,7 +2058,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 999d78d01c..e98df2d96c 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1539,6 +1539,7 @@ pg_newlocale_from_collation(Oid collid)
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
locstr);
+ result.info.builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
}
else if (collform->collprovider == COLLPROVIDER_LIBC)
{
@@ -1695,6 +1696,8 @@ get_collation_actual_version(char collprovider, const char *collcollate)
return "1";
else if (strcmp(collcollate, "C.UTF-8") == 0)
return "1";
+ else if (strcmp(collcollate, "PG_UNICODE_FAST") == 0)
+ return "1";
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -2480,9 +2483,12 @@ builtin_locale_encoding(const char *locale)
{
if (strcmp(locale, "C") == 0)
return -1;
- if (strcmp(locale, "C.UTF-8") == 0)
+ else if (strcmp(locale, "C.UTF-8") == 0)
+ return PG_UTF8;
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
return PG_UTF8;
+
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("invalid locale name \"%s\" for builtin provider",
@@ -2509,6 +2515,8 @@ builtin_validate_locale(int encoding, const char *locale)
canonical_name = "C";
else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
canonical_name = "C.UTF-8";
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ canonical_name = "PG_UNICODE_FAST";
if (!canonical_name)
ereport(ERROR,
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 0805398e24..9a357e3f90 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -432,6 +432,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
default_locale.info.builtin.locale = MemoryContextStrdup(
TopMemoryContext, datlocale);
+ default_locale.info.builtin.casemap_full = (strcmp(datlocale, "PG_UNICODE_FAST") == 0);
}
else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 30e17bd1d1..262a984d04 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2408,6 +2408,8 @@ setlocales(void)
else if (strcmp(datlocale, "C.UTF-8") == 0 ||
strcmp(datlocale, "C.UTF8") == 0)
canonname = "C.UTF-8";
+ else if (strcmp(datlocale, "PG_UNICODE_FAST") == 0)
+ canonname = "PG_UNICODE_FAST";
else
pg_fatal("invalid locale name \"%s\" for builtin provider",
datlocale);
@@ -2704,7 +2706,9 @@ setup_locale_encoding(void)
if (locale_provider == COLLPROVIDER_BUILTIN)
{
- if (strcmp(datlocale, "C.UTF-8") == 0 && encodingid != PG_UTF8)
+ if ((strcmp(datlocale, "C.UTF-8") == 0 ||
+ strcmp(datlocale, "PG_UNICODE_FAST") == 0) &&
+ encodingid != PG_UTF8)
pg_fatal("builtin provider locale \"%s\" requires encoding \"%s\"",
datlocale, "UTF-8");
}
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index dcf554bbd5..82a2fc582d 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -33,5 +33,8 @@
{ oid => '811', descr => 'sorts by Unicode code point; Unicode and POSIX character semantics',
collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
colllocale => 'C.UTF-8', collversion => '1' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST', collversion => '1' },
]
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 41659cdbbd..51e98e759e 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -81,6 +81,7 @@ struct pg_locale_struct
struct
{
const char *locale;
+ bool casemap_full;
} builtin;
locale_t lt;
#ifdef USE_ICU
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index eff0ef21ac..63327a8fdd 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -134,3 +134,163 @@ SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
t
(1 row)
+--
+-- Test PG_UNICODE_FAST
+--
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+ERROR: invalid locale name "unicode" for builtin provider
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123Abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_unicode_fast;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index 1f5f9ef491..c63928d38e 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -65,3 +65,63 @@ SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+
+--
+-- Test PG_UNICODE_FAST
+--
+
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+
+DROP TABLE test_pg_unicode_fast;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-22 14:51 ` Peter Eisentraut <[email protected]>
2024-03-22 17:26 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
4 siblings, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-22 14:51 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 21.03.24 01:13, Jeff Davis wrote:
>> Are there any test cases that illustrate the word boundary changes in
>> patch 0005? It might be useful to test those against Oracle as well.
> The tests include initcap('123abc') which is '123abc' in the PG_C_UTF8
> collation vs '123Abc' in PG_UNICODE_FAST.
>
> The reason for the latter behavior is that the Unicode Default Case
> Conversion algorithm for toTitlecase() advances to the next Cased
> character before mapping to titlecase, and digits are not Cased. ICU
> has a configurable adjustment, and defaults in a way that produces
> '123abc'.
I think this might be too big of a compatibility break. So far,
initcap('123abc') has always returned '123abc'. If the new collation
returns '123Abc' now, then that's quite a change. These are not some
obscure Unicode special case characters, after all.
What is the ICU configuration incantation for this? Maybe we could have
the builtin provider understand some of that, too.
Or we should create a function separate from initcap.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-22 14:51 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-03-22 17:26 ` Jeff Davis <[email protected]>
2024-03-25 07:29 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-22 17:26 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Fri, 2024-03-22 at 15:51 +0100, Peter Eisentraut wrote:
> I think this might be too big of a compatibility break. So far,
> initcap('123abc') has always returned '123abc'. If the new collation
> returns '123Abc' now, then that's quite a change. These are not some
> obscure Unicode special case characters, after all.
It's a new collation, so I'm not sure it's a compatibility break. But
you are right that it is against documentation and expectations for
INITCAP().
> What is the ICU configuration incantation for this? Maybe we could
> have
> the builtin provider understand some of that, too.
https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/stringoptions_8h.html#a4975f537b9960f0330b23...
https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/stringoptions_8h.html#afc65fa226cac9b8eeef0e...
> Or we should create a function separate from initcap.
If we create a new function, that also gives us the opportunity to
accept optional arguments to control the behavior rather than relying
on collation for every decision.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-22 14:51 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-22 17:26 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-25 07:29 ` Peter Eisentraut <[email protected]>
2024-03-25 17:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-25 07:29 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 22.03.24 18:26, Jeff Davis wrote:
> On Fri, 2024-03-22 at 15:51 +0100, Peter Eisentraut wrote:
>> I think this might be too big of a compatibility break. So far,
>> initcap('123abc') has always returned '123abc'. If the new collation
>> returns '123Abc' now, then that's quite a change. These are not some
>> obscure Unicode special case characters, after all.
>
> It's a new collation, so I'm not sure it's a compatibility break. But
> you are right that it is against documentation and expectations for
> INITCAP().
>
>> What is the ICU configuration incantation for this? Maybe we could
>> have
>> the builtin provider understand some of that, too.
>
> https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/stringoptions_8h.html#a4975f537b9960f0330b23...
> https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/stringoptions_8h.html#afc65fa226cac9b8eeef0e...
>
>> Or we should create a function separate from initcap.
>
> If we create a new function, that also gives us the opportunity to
> accept optional arguments to control the behavior rather than relying
> on collation for every decision.
Right. I thought when you said there is an ICU configuration for it,
that it might be like collation options that you specify in the locale
string. But it appears it is only an internal API setting. So that, in
my mind, reinforces the opinion that we should leave initcap() as is and
make a new function that exposes the new functionality. (This does not
have to be part of this patch set.)
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-22 14:51 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-22 17:26 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-25 07:29 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-03-25 17:52 ` Jeff Davis <[email protected]>
2024-03-26 07:14 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-25 17:52 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Mon, 2024-03-25 at 08:29 +0100, Peter Eisentraut wrote:
> Right. I thought when you said there is an ICU configuration for it,
> that it might be like collation options that you specify in the
> locale
> string. But it appears it is only an internal API setting. So that,
> in
> my mind, reinforces the opinion that we should leave initcap() as is
> and
> make a new function that exposes the new functionality. (This does
> not
> have to be part of this patch set.)
OK, I'll propose a "title" or "titlecase" function for 18, along with
"casefold" (which I was already planning to propose).
What do you think about UPPER/LOWER and full case mapping? Should there
be extra arguments for full vs simple case mapping, or should it come
from the collation?
It makes sense that the "dotted vs dotless i" behavior comes from the
collation because that depends on locale. But full-vs-simple case
mapping is not really a locale question. For instance:
select lower('0Σ' collate "en-US-x-icu") AS lower_sigma,
lower('ΑΣ' collate "en-US-x-icu") AS lower_final_sigma,
upper('ß' collate "en-US-x-icu") AS upper_eszett;
lower_sigma | lower_final_sigma | upper_eszett
-------------+-------------------+--------------
0σ | ας | SS
produces the same results for any ICU collation.
There's also another reason to consider it an argument rather than a
collation property, which is that it might be dependent on some other
field in a row. I could imagine someone wanting to do:
SELECT
UPPER(some_field,
full => true,
dotless_i => CASE other_field WHEN ...)
FROM ...
That makes sense for a function in the target list, because different
customers might be from different locales and therefore want different
treatment of the dotted-vs-dotless-i.
Thoughts? Should we use the collation by default but then allow
parameters to override? Or should we just consider this a new set of
functions?
(All of this is v18 material, of course.)
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-22 14:51 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-22 17:26 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-25 07:29 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-25 17:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-26 07:14 ` Peter Eisentraut <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-26 07:14 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 25.03.24 18:52, Jeff Davis wrote:
> OK, I'll propose a "title" or "titlecase" function for 18, along with
> "casefold" (which I was already planning to propose).
(Yay, casefold will be useful.)
> What do you think about UPPER/LOWER and full case mapping? Should there
> be extra arguments for full vs simple case mapping, or should it come
> from the collation?
>
> It makes sense that the "dotted vs dotless i" behavior comes from the
> collation because that depends on locale. But full-vs-simple case
> mapping is not really a locale question. For instance:
>
> select lower('0Σ' collate "en-US-x-icu") AS lower_sigma,
> lower('ΑΣ' collate "en-US-x-icu") AS lower_final_sigma,
> upper('ß' collate "en-US-x-icu") AS upper_eszett;
> lower_sigma | lower_final_sigma | upper_eszett
> -------------+-------------------+--------------
> 0σ | ας | SS
>
> produces the same results for any ICU collation.
I think of a collation describing what language a text is in. So it
makes sense that "dotless i" depends on the locale/collation.
Full vs. simple case mapping is more of a legacy compatibility question,
in my mind. There is some expectation/precedent that C.UTF-8 uses
simple case mapping, but beyond that, I don't see a reason why someone
would want to explicitly opt for simple case mapping, other than if they
need length preservation or something, but if they need that, then they
are going to be in a world of pain in Unicode anyway.
> There's also another reason to consider it an argument rather than a
> collation property, which is that it might be dependent on some other
> field in a row. I could imagine someone wanting to do:
>
> SELECT
> UPPER(some_field,
> full => true,
> dotless_i => CASE other_field WHEN ...)
> FROM ...
Can you index this usefully? It would only work if the user query
matches exactly this pattern?
> That makes sense for a function in the target list, because different
> customers might be from different locales and therefore want different
> treatment of the dotted-vs-dotless-i.
There is also the concept of a session collation, which we haven't
implemented, but it would address this kind of use. But there again the
problem is indexing. But maybe indexing isn't as important for case
conversion as it is for sorting.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-24 11:00 ` Alexander Lakhin <[email protected]>
2024-03-24 23:41 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
4 siblings, 1 reply; 94+ messages in thread
From: Alexander Lakhin @ 2024-03-24 11:00 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
Hello Jeff,
21.03.2024 03:13, Jeff Davis wrote:
> On Tue, 2024-03-19 at 13:41 +0100, Peter Eisentraut wrote:
>> * v25-0002-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch
>>
>> Looks ok.
> Committed.
Please look at a Valgrind-detected error caused by the following query
(starting from f69319f2f):
SELECT lower('Π' COLLATE pg_c_utf8);
==00:00:00:03.487 1429669== Invalid read of size 1
==00:00:00:03.487 1429669== at 0x7C64A5: convert_case (unicode_case.c:107)
==00:00:00:03.487 1429669== by 0x7C6666: unicode_strlower (unicode_case.c:70)
==00:00:00:03.487 1429669== by 0x66B218: str_tolower (formatting.c:1698)
==00:00:00:03.488 1429669== by 0x6D6C55: lower (oracle_compat.c:55)
Best regards,
Alexander
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-24 11:00 ` Re: Built-in CTYPE provider Alexander Lakhin <[email protected]>
@ 2024-03-24 23:41 ` Jeff Davis <[email protected]>
2024-03-25 07:07 ` Re: Built-in CTYPE provider Laurenz Albe <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-03-24 23:41 UTC (permalink / raw)
To: Alexander Lakhin <[email protected]>; Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Sun, 2024-03-24 at 14:00 +0300, Alexander Lakhin wrote:
> Please look at a Valgrind-detected error caused by the following
> query
> (starting from f69319f2f):
> SELECT lower('Π' COLLATE pg_c_utf8);
Thank you for the report!
Fixed in 503c0ad976.
Valgrind did not detect the problem in my setup, so I added a unit test
in case_test.c where it's easier to see the valgrind problem.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-24 11:00 ` Re: Built-in CTYPE provider Alexander Lakhin <[email protected]>
2024-03-24 23:41 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-25 07:07 ` Laurenz Albe <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Laurenz Albe @ 2024-03-25 07:07 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Alexander Lakhin <[email protected]>; Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
There is no technical content in this mail, but I'd like to
show appreciation for your work on this. I hope this will
eventually remove one of the great embarrassments when using
PostgreSQL: the dependency on operation system collations.
Yours,
Laurenz Albe
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-26 07:04 ` Peter Eisentraut <[email protected]>
2024-03-27 22:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-04-01 19:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
4 siblings, 2 replies; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-26 07:04 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 21.03.24 01:13, Jeff Davis wrote:
> The v26 patch was not quite complete, so I didn't commit it yet.
> Attached v27-0001 and 0002.
>
> 0002 is necessary because otherwise lc_collate_is_c() short-circuits
> the version check in pg_newlocale_from_collation(). With 0002, the code
> is simpler and all paths go through pg_newlocale_from_collation(), and
> the version check happens even when lc_collate_is_c().
>
> But perhaps there was a reason the code was the way it was, so
> submitting for review in case I missed something.
>
>> 0005 and 0006 don't contain any test cases. So I guess they are
>> really
>> only usable via 0007. Is that understanding correct?
> 0005 is not a functional change, it's just a refactoring to use a
> callback, which is preparation for 0007.
>
>> Are there any test cases that illustrate the word boundary changes in
>> patch 0005? It might be useful to test those against Oracle as well.
> The tests include initcap('123abc') which is '123abc' in the PG_C_UTF8
> collation vs '123Abc' in PG_UNICODE_FAST.
>
> The reason for the latter behavior is that the Unicode Default Case
> Conversion algorithm for toTitlecase() advances to the next Cased
> character before mapping to titlecase, and digits are not Cased. ICU
> has a configurable adjustment, and defaults in a way that produces
> '123abc'.
>
> New rebased series attached.
The patch set v27 is ok with me, modulo (a) discussion about initcap
semantics, and (b) what collation to assign to ucs_basic, which can be
revisited later.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-26 07:04 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-03-27 22:13 ` Jeff Davis <[email protected]>
1 sibling, 0 replies; 94+ messages in thread
From: Jeff Davis @ 2024-03-27 22:13 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Tue, 2024-03-26 at 08:04 +0100, Peter Eisentraut wrote:
> The patch set v27 is ok with me, modulo (a) discussion about initcap
> semantics, and (b) what collation to assign to ucs_basic, which can
> be
> revisited later.
I held off on the refactoring patch for lc_{ctype|collate}_is_c().
There's an explicit "NB: pg_newlocale_from_collation is only supposed
to be called on non-C-equivalent locales" comment in DefineCollation().
What I'd like to do is make it possible to create valid pg_locale_t
objects out of C locales, which can be used anywhere a real locale can
be used. Callers can still check lc_{collate|ctype}_is_c() for various
reasons; but if they did call pg_newlocale_from_collation on a C locale
it would at least work for the pg_locale.h APIs. That would be a
slightly simpler and safer API, and make it easier to do the collation
version check consistently.
That's not very complicated, but it's a bit invasive and probably out
of scope for v17. It might be part of another change I had intended for
a while, which is to make NULL an invalid pg_locale_t, and use a
different representation to mean "use the server environment". That
would clean up a lot of checks for NULL.
For now, we'd still like to add the version number to the builtin
collations, so that leaves us with two options:
(a) Perform the version check in lc_{collate|ctype}_is_c(), which
duplicates some code and creates some inconsistency in how the version
is checked for different providers.
(b) Don't worry about it and just commit the version change in v27-
0001. The version check is already performed correctly on the database
without changes, even if the locale is "C". And there are already three
built-in "C" collations: "C", "POSIX", and UCS_BASIC; so it's not clear
why someone would create even more of them. And even if they did, there
would be no reason to give them a warning because we haven't
incremented the version, so there's no chance of a mismatch.
I'm inclined toward (b). Thoughts?
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-26 07:04 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-04-01 19:52 ` Jeff Davis <[email protected]>
2024-04-04 12:05 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
1 sibling, 1 reply; 94+ messages in thread
From: Jeff Davis @ 2024-04-01 19:52 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Tue, 2024-03-26 at 08:04 +0100, Peter Eisentraut wrote:
> The patch set v27 is ok with me, modulo (a) discussion about initcap
> semantics, and (b) what collation to assign to ucs_basic, which can
> be
> revisited later.
Attached v28.
The remaining patches are for full case mapping and PG_UNICODE_FAST.
I am fine waiting until July to get these remaining patches committed.
That would give us time to sort out details like:
* Get consensus that it's OK to change UCS_BASIC.
* Figure out if we need a pg-specific locale and whether
PG_UNICODE_FAST is the right name.
* Make sure that full case mapping interacts with regexes in a sane way
(probably it needs to just fall back to simple case mapping, but
perhaps that's worth a discussion).
* Implement case folding.
* Implement a more unicode-friendly TITLECASE() function, which could
offer a number of options that don't fit well with INITCAP().
* Figure out if UPPER()/LOWER() should also have some of those options.
Thoughts?
Regards,
Jeff Davis
Attachments:
[text/x-patch] v28-0001-Support-Unicode-full-case-mapping-and-conversion.patch (559.6K, ../../[email protected]/2-v28-0001-Support-Unicode-full-case-mapping-and-conversion.patch)
download | inline diff:
From 3514bd1926d31404662d84da8d548caf92f11b98 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Sat, 9 Mar 2024 12:55:21 -0800
Subject: [PATCH v28 1/2] Support Unicode full case mapping and conversion.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Generate tables from Unicode SpecialCasing.txt to support more
sophisticated case mapping behavior:
* support case mappings to multiple codepoints, such as "ß"
uppercasing to "SS"
* support conditional case mappings, such as the "final sigma"
* support titlecase variants, such as "dž" uppercasing to "DŽ" but
titlecasing to "Dž"
Discussion: https://postgr.es/m/[email protected]
---
src/backend/utils/adt/formatting.c | 12 +-
src/common/unicode/Makefile | 4 +-
src/common/unicode/case_test.c | 47 +-
.../unicode/generate-unicode_case_table.pl | 161 +-
src/common/unicode/meson.build | 4 +-
src/common/unicode_case.c | 185 +-
src/include/common/unicode_case.h | 8 +-
src/include/common/unicode_case_table.h | 6094 +++++++++--------
8 files changed, 3517 insertions(+), 2998 deletions(-)
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 8736ada4be..c2acc6c312 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,13 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen);
+ needed = unicode_strlower(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -1843,13 +1843,13 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen);
+ needed = unicode_strupper(dst, dstsize, src, srclen, false);
Assert(needed + 1 == dstsize);
}
@@ -2040,7 +2040,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2051,7 +2051,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen,
+ needed = unicode_strtitle(dst, dstsize, src, srclen, false,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/common/unicode/Makefile b/src/common/unicode/Makefile
index c38ab36b1e..87d7355794 100644
--- a/src/common/unicode/Makefile
+++ b/src/common/unicode/Makefile
@@ -30,7 +30,7 @@ update-unicode: unicode_case_table.h unicode_category_table.h unicode_east_asian
# These files are part of the Unicode Character Database. Download
# them on demand. The dependency on Makefile.global is for
# UNICODE_VERSION.
-CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
+CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt: $(top_builddir)/src/Makefile.global
$(DOWNLOAD) https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/$(@F)
unicode_version.h: generate-unicode_version.pl
@@ -91,4 +91,4 @@ clean:
rm -f $(OBJS) case_test case_test.o category_test category_test.o norm_test norm_test.o
distclean: clean
- rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
+ rm -f CompositionExclusions.txt DerivedCoreProperties.txt DerivedNormalizationProps.txt EastAsianWidth.txt NormalizationTest.txt PropList.txt SpecialCasing.txt UnicodeData.txt norm_test_table.h unicode_case_table.h unicode_category_table.h unicode_norm_table.h
diff --git a/src/common/unicode/case_test.c b/src/common/unicode/case_test.c
index 85a43decb8..1a2756b302 100644
--- a/src/common/unicode/case_test.c
+++ b/src/common/unicode/case_test.c
@@ -24,6 +24,9 @@
#include "common/unicode_category.h"
#include "common/unicode_version.h"
+typedef size_t (*TestFunc) (char *dst, size_t dstsize, const char *src,
+ ssize_t srclen);
+
#ifdef USE_ICU
static void
@@ -86,7 +89,7 @@ test_icu(void)
#endif
static void
-test_strlower(const char *test_string, const char *expected)
+test_convert(TestFunc tfunc, const char *test_string, const char *expected)
{
size_t src1len = strlen(test_string);
size_t src2len = -1; /* NUL-terminated */
@@ -102,10 +105,11 @@ test_strlower(const char *test_string, const char *expected)
/* neither source nor destination are NUL-terminated */
memset(dst1, 0x7F, dst1len);
- needed = unicode_strlower(dst1, dst1len, src1, src1len);
+ needed = tfunc(dst1, dst1len, src1, src1len);
if (needed != strlen(expected))
{
- printf("case_test: convert_case test1 FAILURE: needed %zu\n", needed);
+ printf("case_test: convert_case test1 FAILURE: '%s' needed %zu expected %zu\n",
+ test_string, needed, strlen(expected));
exit(1);
}
if (memcmp(dst1, expected, dst1len) != 0)
@@ -117,10 +121,11 @@ test_strlower(const char *test_string, const char *expected)
/* destination is NUL-terminated and source is not */
memset(dst2, 0x7F, dst2len);
- needed = unicode_strlower(dst2, dst2len, src1, src1len);
+ needed = tfunc(dst2, dst2len, src1, src1len);
if (needed != strlen(expected))
{
- printf("case_test: convert_case test2 FAILURE: needed %zu\n", needed);
+ printf("case_test: convert_case test2 FAILURE: '%s' needed %zu expected %zu\n",
+ test_string, needed, strlen(expected));
exit(1);
}
if (strcmp(dst2, expected) != 0)
@@ -132,9 +137,11 @@ test_strlower(const char *test_string, const char *expected)
/* source is NUL-terminated and destination is not */
memset(dst1, 0x7F, dst1len);
- needed = unicode_strlower(dst1, dst1len, src2, src2len);
+ needed = tfunc(dst1, dst1len, src2, src2len);
if (needed != strlen(expected))
{
+ printf("case_test: convert_case test3 FAILURE: '%s' needed %zu expected %zu\n",
+ test_string, needed, strlen(expected));
printf("case_test: convert_case test3 FAILURE: needed %zu\n", needed);
exit(1);
}
@@ -147,10 +154,11 @@ test_strlower(const char *test_string, const char *expected)
/* both source and destination are NUL-terminated */
memset(dst2, 0x7F, dst2len);
- needed = unicode_strlower(dst2, dst2len, src2, src2len);
+ needed = tfunc(dst2, dst2len, src2, src2len);
if (needed != strlen(expected))
{
- printf("case_test: convert_case test4 FAILURE: needed %zu\n", needed);
+ printf("case_test: convert_case test4 FAILURE: '%s' needed %zu expected %zu\n",
+ test_string, needed, strlen(expected));
exit(1);
}
if (strcmp(dst2, expected) != 0)
@@ -166,15 +174,32 @@ test_strlower(const char *test_string, const char *expected)
free(dst2);
}
+static size_t
+tfunc_lower(char *dst, size_t dstsize, const char *src,
+ ssize_t srclen)
+{
+ return unicode_strlower(dst, dstsize, src, srclen, true);
+}
+
+static size_t
+tfunc_upper(char *dst, size_t dstsize, const char *src,
+ ssize_t srclen)
+{
+ return unicode_strupper(dst, dstsize, src, srclen, true);
+}
+
+
static void
test_convert_case()
{
/* test string with no case changes */
- test_strlower("√∞", "√∞");
+ test_convert(tfunc_lower, "√∞", "√∞");
/* test string with case changes */
- test_strlower("ABC", "abc");
+ test_convert(tfunc_upper, "abc", "ABC");
/* test string with case changes and byte length changes */
- test_strlower("ȺȺȺ", "ⱥⱥⱥ");
+ test_convert(tfunc_lower, "ȺȺȺ", "ⱥⱥⱥ");
+ /* test special case conversions */
+ test_convert(tfunc_upper, "ß", "SS");
printf("case_test: convert_case: success\n");
}
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
index 44b785b861..02da4b682f 100644
--- a/src/common/unicode/generate-unicode_case_table.pl
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -3,7 +3,7 @@
# Generate Unicode character case mappings. Does not include tailoring
# or locale-specific mappings.
#
-# Input: UnicodeData.txt
+# Input: SpecialCasing.txt UnicodeData.txt
# Output: unicode_case_table.h
#
# Copyright (c) 2000-2023, PostgreSQL Global Development Group
@@ -21,6 +21,10 @@ GetOptions('outdir:s' => \$output_path);
my $output_table_file = "$output_path/unicode_case_table.h";
+# The maximum number of codepoints that can result from case mapping
+# of a single character. See Unicode section 5.18 "Case Mappings".
+my $MAX_CASE_EXPANSION = 3;
+
my $FH;
my %simple = ();
@@ -51,6 +55,98 @@ while (my $line = <$FH>)
}
close $FH;
+# Map for special casing rules that aren't represented in the simple
+# mapping. Language-sensitive mappings are not supported.
+#
+# See https://www.unicode.org/reports/tr44/#SpecialCasing.txt, or the
+# SpecialCasing.txt file itself for details.
+
+# for now, only Final_Sigma is supported
+my %condition_map = (Final_Sigma => 'PG_U_FINAL_SIGMA');
+
+my %special = ();
+open($FH, '<', "$output_path/SpecialCasing.txt")
+ or die "Could not open $output_path/SpecialCasing.txt: $!.";
+while (my $line = <$FH>)
+{
+ # language-sensitive mappings not supported
+ last if $line =~ /\# Language-Sensitive Mappings/;
+
+ # remove comments
+ $line =~ s/^(.*?)#.*$/$1/s;
+
+ # ignore empty lines
+ next unless $line =~ /;/;
+
+ my @elts = split /;/, $line;
+ my $code = hex($elts[0]);
+
+ # Codepoint may map to multiple characters when converting
+ # case. Split each mapping on whitespace and extract the
+ # hexadecimal into an array of codepoints.
+ my @lower = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[1]));
+ my @title = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[2]));
+ my @upper = map { hex $_ } (grep /[09A-F]+/, (split /\s+/, $elts[3]));
+ my @conditions = map {
+ # supporting negated conditions may require storing a
+ # mask of relevant conditions for a given rule to differentiate
+ # between lack of a condition and a negated condition
+ die "negated conditions not supported" if /^Not_/;
+ $condition_map{$_} || die "unrecognized condition: $_"
+ } (grep /\w+/, (split /\s+/, $elts[4]));
+
+ my $cond_str = (join '|', @conditions) || '0';
+
+ # if empty, create a self-mapping
+ push @lower, $code if (scalar @lower == 0);
+ push @title, $code if (scalar @title == 0);
+ push @upper, $code if (scalar @upper == 0);
+
+ # none should map to more than 3 codepoints
+ die "lowercase expansion for 0x$elts[0] exceeds maximum: '$elts[1]'"
+ if (scalar @lower) > $MAX_CASE_EXPANSION;
+ die "titlecase expansion for 0x$elts[0] exceeds maximum: '$elts[2]'"
+ if (scalar @title) > $MAX_CASE_EXPANSION;
+ die "uppercase expansion for 0x$elts[0] exceeds maximum: '$elts[3]'"
+ if (scalar @upper) > $MAX_CASE_EXPANSION;
+
+ # pad arrays to a fixed length of 3
+ while (scalar @upper < $MAX_CASE_EXPANSION) { push @upper, 0x000000 }
+ while (scalar @lower < $MAX_CASE_EXPANSION) { push @lower, 0x000000 }
+ while (scalar @title < $MAX_CASE_EXPANSION) { push @title, 0x000000 }
+
+ # Characters with special mappings may not have simple mappings;
+ # ensure that an entry exists.
+ $simple{$code} ||= {
+ Simple_Lowercase => $code,
+ Simple_Titlecase => $code,
+ Simple_Uppercase => $code
+ };
+
+ # Multiple special case rules for a single codepoint could be
+ # supported by making several entries for each codepoint, and have
+ # the simple mapping point to the first entry. The caller could
+ # scan forward looking for an entry that matches the conditions,
+ # or fall back to the normal behavior.
+ die "multiple special case mappings not supported"
+ if defined $special{$code};
+
+ $special{$code} = {
+ Uppercase => \@upper,
+ Lowercase => \@lower,
+ Titlecase => \@title,
+ Conditions => $cond_str
+ };
+}
+close $FH;
+
+# assign sequential array indexes to the special mappings
+my $special_idx = 0;
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ $special{$code}{Index} = $special_idx++;
+}
+
# Start writing out the output files
open my $OT, '>', $output_table_file
or die "Could not open output file $output_table_file: $!\n";
@@ -63,6 +159,8 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
$num_simple++ unless $code < 0x80;
}
+my $num_special = scalar(keys %special) + 1;
+
print $OT <<"EOS";
/*-------------------------------------------------------------------------
*
@@ -86,6 +184,19 @@ print $OT <<"EOS";
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -94,12 +205,47 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[$num_special] =
+{
+EOS
+
+foreach my $code (sort { $a <=> $b } (keys %special))
+{
+ die if scalar @{ $special{$code}{Lowercase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Titlecase} } != $MAX_CASE_EXPANSION;
+ die if scalar @{ $special{$code}{Uppercase} } != $MAX_CASE_EXPANSION;
+ my $lower = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Lowercase} });
+ my $title = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Titlecase} });
+ my $upper = join ", ",
+ (map { sprintf "0x%06x", $_ } @{ $special{$code}{Uppercase} });
+ printf $OT "\t{0x%06x, %s, ", $code, $special{$code}{Conditions};
+ printf $OT "{{%s}, {%s}, {%s}}},\n", $lower, $title, $upper;
+}
+
+print $OT "\t{0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}\n";
+print $OT <<"EOS";
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
@@ -114,8 +260,10 @@ for (my $code = 0; $code < 0x80; $code++)
my $lc = ($simple{$code}{Simple_Lowercase} || $code);
my $tc = ($simple{$code}{Simple_Titlecase} || $code);
my $uc = ($simple{$code}{Simple_Uppercase} || $code);
+ die "unexpected special case for code $code"
+ if defined $special{$code};
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, NULL},\n",
$code, $lc, $tc, $uc;
}
printf $OT "\n";
@@ -126,9 +274,14 @@ foreach my $code (sort { $a <=> $b } (keys %simple))
next unless $code >= 0x80; # already output above
my $map = $simple{$code};
+ my $special_case = "NULL";
+ if (exists $special{$code})
+ {
+ $special_case = sprintf "&special_case[%d]", $special{$code}{Index};
+ }
printf $OT
- "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}},\n",
+ "\t{0x%06x, {[CaseLower] = 0x%06x,[CaseTitle] = 0x%06x,[CaseUpper] = 0x%06x}, %s},\n",
$code, $map->{Simple_Lowercase}, $map->{Simple_Titlecase},
- $map->{Simple_Uppercase};
+ $map->{Simple_Uppercase}, $special_case;
}
print $OT "};\n";
diff --git a/src/common/unicode/meson.build b/src/common/unicode/meson.build
index b9a4181c32..554564c093 100644
--- a/src/common/unicode/meson.build
+++ b/src/common/unicode/meson.build
@@ -11,7 +11,7 @@ endif
# These files are part of the Unicode Character Database. Download them on
# demand.
-foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'UnicodeData.txt']
+foreach f : ['CompositionExclusions.txt', 'DerivedCoreProperties.txt', 'DerivedNormalizationProps.txt', 'EastAsianWidth.txt', 'NormalizationTest.txt', 'PropList.txt', 'SpecialCasing.txt', 'UnicodeData.txt']
url = unicode_baseurl.format(UNICODE_VERSION, f)
target = custom_target(f,
output: f,
@@ -26,7 +26,7 @@ update_unicode_targets = []
update_unicode_targets += \
custom_target('unicode_case_table.h',
- input: [unicode_data['UnicodeData.txt']],
+ input: [unicode_data['SpecialCasing.txt'], unicode_data['UnicodeData.txt']],
output: ['unicode_case_table.h'],
command: [
perl, files('generate-unicode_case_table.pl'),
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index bc423b0890..94d2ee9931 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -22,8 +22,10 @@
static const pg_case_map *find_case_map(pg_wchar ucs);
static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext,
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
+static bool check_special_conditions(int conditions, const char *str,
+ size_t len, size_t offset);
pg_wchar
unicode_lowercase_simple(pg_wchar code)
@@ -64,11 +66,16 @@ unicode_uppercase_simple(pg_wchar code)
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseLower, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseLower, full, NULL,
+ NULL);
}
/*
@@ -87,6 +94,13 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
*
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied; use titlecase mapping for the first character;
+ * and perform adjustment to the first Cased character after a word
+ * boundary. If full is false, use only simple mappings; use uppercase mapping
+ * for the first character; and map the first character of each word to
+ * uppercase.
+ *
* Titlecasing requires knowledge about word boundaries, which is provided by
* the callback wbnext. A word boundary is the offset of the start of a word
* or the offset of the character immediately following a word.
@@ -98,9 +112,9 @@ unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen)
*/
size_t
unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- WordBoundaryNext wbnext, void *wbstate)
+ bool full, WordBoundaryNext wbnext, void *wbstate)
{
- return convert_case(dst, dstsize, src, srclen, CaseTitle, wbnext,
+ return convert_case(dst, dstsize, src, srclen, CaseTitle, full, wbnext,
wbstate);
}
@@ -119,29 +133,42 @@ unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.
+ *
+ * If full is true, use special case mappings if available and if the
+ * conditions are satisfied.
*/
size_t
-unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+ bool full)
{
- return convert_case(dst, dstsize, src, srclen, CaseUpper, NULL, NULL);
+ return convert_case(dst, dstsize, src, srclen, CaseUpper, full, NULL,
+ NULL);
}
/*
+ * Implement Unicode Default Case Conversion algorithm.
+ *
* If str_casekind is CaseLower or CaseUpper, map each character in the string
* for which a mapping is available.
*
- * If str_casekind is CaseTitle, maps characters found on a word boundary to
- * uppercase and other characters to lowercase.
+ * If str_casekind is CaseTitle: for each word boundary, "adjust" forward to
+ * the next Cased character and map it to titlecase; then map subsequent
+ * characters to lowercase until the next word boundary.
+ *
+ * Some characters have special mappings, which can map a single codepoint to
+ * multiple codepoints, or depend on conditions.
*/
static size_t
convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
- CaseKind str_casekind, WordBoundaryNext wbnext, void *wbstate)
+ CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
+ void *wbstate)
{
/* character CaseKind varies while titlecasing */
CaseKind chr_casekind = str_casekind;
size_t srcoff = 0;
size_t result_len = 0;
size_t boundary = 0;
+ bool adjusting = true;
Assert((str_casekind == CaseTitle && wbnext && wbstate) ||
(str_casekind != CaseTitle && !wbnext && !wbstate));
@@ -156,21 +183,77 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
{
pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
- const pg_case_map *casemap = find_case_map(u1);
+ const pg_case_map *casemap = NULL;
+ const pg_special_case *special = NULL;
+ /*
+ * Titlecasing has two states: adjusting from boundary (initial
+ * state), and lowercasing until the next boundary.
+ */
if (str_casekind == CaseTitle)
{
if (srcoff == boundary)
{
- chr_casekind = CaseUpper;
+ /* reset to initial state and find the next boundary */
+ adjusting = true;
boundary = wbnext(wbstate);
}
+
+ if (adjusting)
+ {
+ if (!full || pg_u_prop_cased(u1))
+ {
+ /* adjustment done: map to titlecase */
+ adjusting = false;
+ chr_casekind = full ? CaseTitle : CaseUpper;
+ casemap = find_case_map(u1);
+ }
+ else
+ casemap = NULL; /* no mapping during adjustment */
+ }
else
+ {
chr_casekind = CaseLower;
+ casemap = find_case_map(u1);
+ }
+ }
+ else
+ casemap = find_case_map(u1);
+
+ /*
+ * Find special case that matches the conditions, if any.
+ *
+ * Note: only a single special mapping per codepoint is currently
+ * supported, though Unicode allows for multiple special mappings for
+ * a single codepoint.
+ */
+ if (full && casemap && casemap->special_case)
+ {
+ int16 conditions = casemap->special_case->conditions;
+
+ Assert(casemap->special_case->codepoint == u1);
+ if (check_special_conditions(conditions, src, srclen, srcoff))
+ special = casemap->special_case;
}
/* perform mapping, update result_len, and write to dst */
- if (casemap)
+ if (special)
+ {
+ for (int i = 0; i < MAX_CASE_EXPANSION; i++)
+ {
+ pg_wchar u2 = special->map[chr_casekind][i];
+ size_t u2len = unicode_utf8len(u2);
+
+ if (u2 == '\0')
+ break;
+
+ if (result_len + u2len <= dstsize)
+ unicode_to_utf8(u2, (unsigned char *) dst + result_len);
+
+ result_len += u2len;
+ }
+ }
+ else if (casemap)
{
pg_wchar u2 = casemap->simplemap[chr_casekind];
pg_wchar u2len = unicode_utf8len(u2);
@@ -198,6 +281,82 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
return result_len;
}
+/*
+ * Check that the condition matches Final_Sigma, described in Unicode Table
+ * 3-17. The character at the given offset must be directly preceded by a
+ * Cased character, and must not be directly followed by a Cased character.
+ *
+ * Case_Ignorable characters are ignored. NB: some characters may be both
+ * Cased and Case_Ignorable, in which case they are ignored.
+ */
+static bool
+check_final_sigma(const unsigned char *str, size_t len, size_t offset)
+{
+ /* the start of the string is not preceded by a Cased character */
+ if (offset == 0)
+ return false;
+
+ /* iterate backwards, looking for Cased character */
+ for (int i = offset - 1; i >= 0; i--)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ break;
+ else
+ return false;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ /* end of string is not followed by a Cased character */
+ if (offset == len)
+ return true;
+
+ /* iterate forwards, looking for Cased character */
+ for (int i = offset + 1; i < len && str[i] != '\0'; i++)
+ {
+ if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
+ {
+ pg_wchar curr = utf8_to_unicode(str + i);
+
+ if (pg_u_prop_case_ignorable(curr))
+ continue;
+ else if (pg_u_prop_cased(curr))
+ return false;
+ else
+ break;
+ }
+ else if ((str[i] & 0xC0) == 0x80)
+ continue;
+
+ Assert(false); /* invalid UTF-8 */
+ }
+
+ return true;
+}
+
+static bool
+check_special_conditions(int conditions, const char *str, size_t len,
+ size_t offset)
+{
+ if (conditions == 0)
+ return true;
+ else if (conditions == PG_U_FINAL_SIGMA)
+ return check_final_sigma((unsigned char *) str, len, offset);
+
+ /* no other conditions supported */
+ Assert(false);
+ return false;
+}
+
/* find entry in simple case map, if any */
static const pg_case_map *
find_case_map(pg_wchar ucs)
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index c0c3382e79..c982815823 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -22,11 +22,11 @@ pg_wchar unicode_lowercase_simple(pg_wchar ucs);
pg_wchar unicode_titlecase_simple(pg_wchar ucs);
pg_wchar unicode_uppercase_simple(pg_wchar ucs);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, WordBoundaryNext wbnext,
- void *wbstate);
+ ssize_t srclen, bool full,
+ WordBoundaryNext wbnext, void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ ssize_t srclen, bool full);
#endif /* UNICODE_CASE_H */
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
index b239f0b3c3..081d4133b1 100644
--- a/src/include/common/unicode_case_table.h
+++ b/src/include/common/unicode_case_table.h
@@ -20,6 +20,19 @@
#include "common/unicode_case.h"
#include "mb/pg_wchar.h"
+/*
+ * The maximum number of codepoints that can result from case mapping
+ * of a single character. See Unicode section 5.18 "Case Mappings".
+ */
+#define MAX_CASE_EXPANSION 3
+
+/*
+ * Case mapping condition flags. For now, only Final_Sigma is supported.
+ *
+ * See Unicode Context Specification for Casing.
+ */
+#define PG_U_FINAL_SIGMA (1 << 0)
+
typedef enum
{
CaseLower = 0,
@@ -28,2974 +41,3143 @@ typedef enum
NCaseKind
} CaseKind;
+typedef struct
+{
+ pg_wchar codepoint; /* Unicode codepoint */
+ int16 conditions;
+ pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+} pg_special_case;
+
typedef struct
{
pg_wchar codepoint; /* Unicode codepoint */
pg_wchar simplemap[NCaseKind];
+ const pg_special_case *special_case;
} pg_case_map;
+/*
+ * Special case mappings that aren't representable in the simple map.
+ * Entries are referenced from simple_case_map.
+ */
+static const pg_special_case special_case[105] =
+{
+ {0x0000df, 0, {{0x0000df, 0x000000, 0x000000}, {0x000053, 0x000073, 0x000000}, {0x000053, 0x000053, 0x000000}}},
+ {0x000130, 0, {{0x000069, 0x000307, 0x000000}, {0x000130, 0x000000, 0x000000}, {0x000130, 0x000000, 0x000000}}},
+ {0x000149, 0, {{0x000149, 0x000000, 0x000000}, {0x0002bc, 0x00004e, 0x000000}, {0x0002bc, 0x00004e, 0x000000}}},
+ {0x0001f0, 0, {{0x0001f0, 0x000000, 0x000000}, {0x00004a, 0x00030c, 0x000000}, {0x00004a, 0x00030c, 0x000000}}},
+ {0x000390, 0, {{0x000390, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x0003a3, PG_U_FINAL_SIGMA, {{0x0003c2, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}, {0x0003a3, 0x000000, 0x000000}}},
+ {0x0003b0, 0, {{0x0003b0, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x000587, 0, {{0x000587, 0x000000, 0x000000}, {0x000535, 0x000582, 0x000000}, {0x000535, 0x000552, 0x000000}}},
+ {0x001e96, 0, {{0x001e96, 0x000000, 0x000000}, {0x000048, 0x000331, 0x000000}, {0x000048, 0x000331, 0x000000}}},
+ {0x001e97, 0, {{0x001e97, 0x000000, 0x000000}, {0x000054, 0x000308, 0x000000}, {0x000054, 0x000308, 0x000000}}},
+ {0x001e98, 0, {{0x001e98, 0x000000, 0x000000}, {0x000057, 0x00030a, 0x000000}, {0x000057, 0x00030a, 0x000000}}},
+ {0x001e99, 0, {{0x001e99, 0x000000, 0x000000}, {0x000059, 0x00030a, 0x000000}, {0x000059, 0x00030a, 0x000000}}},
+ {0x001e9a, 0, {{0x001e9a, 0x000000, 0x000000}, {0x000041, 0x0002be, 0x000000}, {0x000041, 0x0002be, 0x000000}}},
+ {0x001f50, 0, {{0x001f50, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000000}, {0x0003a5, 0x000313, 0x000000}}},
+ {0x001f52, 0, {{0x001f52, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000300}, {0x0003a5, 0x000313, 0x000300}}},
+ {0x001f54, 0, {{0x001f54, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000301}, {0x0003a5, 0x000313, 0x000301}}},
+ {0x001f56, 0, {{0x001f56, 0x000000, 0x000000}, {0x0003a5, 0x000313, 0x000342}, {0x0003a5, 0x000313, 0x000342}}},
+ {0x001f80, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f81, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f82, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f83, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f84, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f85, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f86, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f87, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f88, 0, {{0x001f80, 0x000000, 0x000000}, {0x001f88, 0x000000, 0x000000}, {0x001f08, 0x000399, 0x000000}}},
+ {0x001f89, 0, {{0x001f81, 0x000000, 0x000000}, {0x001f89, 0x000000, 0x000000}, {0x001f09, 0x000399, 0x000000}}},
+ {0x001f8a, 0, {{0x001f82, 0x000000, 0x000000}, {0x001f8a, 0x000000, 0x000000}, {0x001f0a, 0x000399, 0x000000}}},
+ {0x001f8b, 0, {{0x001f83, 0x000000, 0x000000}, {0x001f8b, 0x000000, 0x000000}, {0x001f0b, 0x000399, 0x000000}}},
+ {0x001f8c, 0, {{0x001f84, 0x000000, 0x000000}, {0x001f8c, 0x000000, 0x000000}, {0x001f0c, 0x000399, 0x000000}}},
+ {0x001f8d, 0, {{0x001f85, 0x000000, 0x000000}, {0x001f8d, 0x000000, 0x000000}, {0x001f0d, 0x000399, 0x000000}}},
+ {0x001f8e, 0, {{0x001f86, 0x000000, 0x000000}, {0x001f8e, 0x000000, 0x000000}, {0x001f0e, 0x000399, 0x000000}}},
+ {0x001f8f, 0, {{0x001f87, 0x000000, 0x000000}, {0x001f8f, 0x000000, 0x000000}, {0x001f0f, 0x000399, 0x000000}}},
+ {0x001f90, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f91, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f92, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f93, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f94, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f95, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f96, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f97, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001f98, 0, {{0x001f90, 0x000000, 0x000000}, {0x001f98, 0x000000, 0x000000}, {0x001f28, 0x000399, 0x000000}}},
+ {0x001f99, 0, {{0x001f91, 0x000000, 0x000000}, {0x001f99, 0x000000, 0x000000}, {0x001f29, 0x000399, 0x000000}}},
+ {0x001f9a, 0, {{0x001f92, 0x000000, 0x000000}, {0x001f9a, 0x000000, 0x000000}, {0x001f2a, 0x000399, 0x000000}}},
+ {0x001f9b, 0, {{0x001f93, 0x000000, 0x000000}, {0x001f9b, 0x000000, 0x000000}, {0x001f2b, 0x000399, 0x000000}}},
+ {0x001f9c, 0, {{0x001f94, 0x000000, 0x000000}, {0x001f9c, 0x000000, 0x000000}, {0x001f2c, 0x000399, 0x000000}}},
+ {0x001f9d, 0, {{0x001f95, 0x000000, 0x000000}, {0x001f9d, 0x000000, 0x000000}, {0x001f2d, 0x000399, 0x000000}}},
+ {0x001f9e, 0, {{0x001f96, 0x000000, 0x000000}, {0x001f9e, 0x000000, 0x000000}, {0x001f2e, 0x000399, 0x000000}}},
+ {0x001f9f, 0, {{0x001f97, 0x000000, 0x000000}, {0x001f9f, 0x000000, 0x000000}, {0x001f2f, 0x000399, 0x000000}}},
+ {0x001fa0, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa1, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001fa2, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fa3, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fa4, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fa5, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fa6, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001fa7, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fa8, 0, {{0x001fa0, 0x000000, 0x000000}, {0x001fa8, 0x000000, 0x000000}, {0x001f68, 0x000399, 0x000000}}},
+ {0x001fa9, 0, {{0x001fa1, 0x000000, 0x000000}, {0x001fa9, 0x000000, 0x000000}, {0x001f69, 0x000399, 0x000000}}},
+ {0x001faa, 0, {{0x001fa2, 0x000000, 0x000000}, {0x001faa, 0x000000, 0x000000}, {0x001f6a, 0x000399, 0x000000}}},
+ {0x001fab, 0, {{0x001fa3, 0x000000, 0x000000}, {0x001fab, 0x000000, 0x000000}, {0x001f6b, 0x000399, 0x000000}}},
+ {0x001fac, 0, {{0x001fa4, 0x000000, 0x000000}, {0x001fac, 0x000000, 0x000000}, {0x001f6c, 0x000399, 0x000000}}},
+ {0x001fad, 0, {{0x001fa5, 0x000000, 0x000000}, {0x001fad, 0x000000, 0x000000}, {0x001f6d, 0x000399, 0x000000}}},
+ {0x001fae, 0, {{0x001fa6, 0x000000, 0x000000}, {0x001fae, 0x000000, 0x000000}, {0x001f6e, 0x000399, 0x000000}}},
+ {0x001faf, 0, {{0x001fa7, 0x000000, 0x000000}, {0x001faf, 0x000000, 0x000000}, {0x001f6f, 0x000399, 0x000000}}},
+ {0x001fb2, 0, {{0x001fb2, 0x000000, 0x000000}, {0x001fba, 0x000345, 0x000000}, {0x001fba, 0x000399, 0x000000}}},
+ {0x001fb3, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fb4, 0, {{0x001fb4, 0x000000, 0x000000}, {0x000386, 0x000345, 0x000000}, {0x000386, 0x000399, 0x000000}}},
+ {0x001fb6, 0, {{0x001fb6, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000000}, {0x000391, 0x000342, 0x000000}}},
+ {0x001fb7, 0, {{0x001fb7, 0x000000, 0x000000}, {0x000391, 0x000342, 0x000345}, {0x000391, 0x000342, 0x000399}}},
+ {0x001fbc, 0, {{0x001fb3, 0x000000, 0x000000}, {0x001fbc, 0x000000, 0x000000}, {0x000391, 0x000399, 0x000000}}},
+ {0x001fc2, 0, {{0x001fc2, 0x000000, 0x000000}, {0x001fca, 0x000345, 0x000000}, {0x001fca, 0x000399, 0x000000}}},
+ {0x001fc3, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fc4, 0, {{0x001fc4, 0x000000, 0x000000}, {0x000389, 0x000345, 0x000000}, {0x000389, 0x000399, 0x000000}}},
+ {0x001fc6, 0, {{0x001fc6, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000000}, {0x000397, 0x000342, 0x000000}}},
+ {0x001fc7, 0, {{0x001fc7, 0x000000, 0x000000}, {0x000397, 0x000342, 0x000345}, {0x000397, 0x000342, 0x000399}}},
+ {0x001fcc, 0, {{0x001fc3, 0x000000, 0x000000}, {0x001fcc, 0x000000, 0x000000}, {0x000397, 0x000399, 0x000000}}},
+ {0x001fd2, 0, {{0x001fd2, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000300}, {0x000399, 0x000308, 0x000300}}},
+ {0x001fd3, 0, {{0x001fd3, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000301}, {0x000399, 0x000308, 0x000301}}},
+ {0x001fd6, 0, {{0x001fd6, 0x000000, 0x000000}, {0x000399, 0x000342, 0x000000}, {0x000399, 0x000342, 0x000000}}},
+ {0x001fd7, 0, {{0x001fd7, 0x000000, 0x000000}, {0x000399, 0x000308, 0x000342}, {0x000399, 0x000308, 0x000342}}},
+ {0x001fe2, 0, {{0x001fe2, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000300}, {0x0003a5, 0x000308, 0x000300}}},
+ {0x001fe3, 0, {{0x001fe3, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000301}, {0x0003a5, 0x000308, 0x000301}}},
+ {0x001fe4, 0, {{0x001fe4, 0x000000, 0x000000}, {0x0003a1, 0x000313, 0x000000}, {0x0003a1, 0x000313, 0x000000}}},
+ {0x001fe6, 0, {{0x001fe6, 0x000000, 0x000000}, {0x0003a5, 0x000342, 0x000000}, {0x0003a5, 0x000342, 0x000000}}},
+ {0x001fe7, 0, {{0x001fe7, 0x000000, 0x000000}, {0x0003a5, 0x000308, 0x000342}, {0x0003a5, 0x000308, 0x000342}}},
+ {0x001ff2, 0, {{0x001ff2, 0x000000, 0x000000}, {0x001ffa, 0x000345, 0x000000}, {0x001ffa, 0x000399, 0x000000}}},
+ {0x001ff3, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x001ff4, 0, {{0x001ff4, 0x000000, 0x000000}, {0x00038f, 0x000345, 0x000000}, {0x00038f, 0x000399, 0x000000}}},
+ {0x001ff6, 0, {{0x001ff6, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000000}, {0x0003a9, 0x000342, 0x000000}}},
+ {0x001ff7, 0, {{0x001ff7, 0x000000, 0x000000}, {0x0003a9, 0x000342, 0x000345}, {0x0003a9, 0x000342, 0x000399}}},
+ {0x001ffc, 0, {{0x001ff3, 0x000000, 0x000000}, {0x001ffc, 0x000000, 0x000000}, {0x0003a9, 0x000399, 0x000000}}},
+ {0x00fb00, 0, {{0x00fb00, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000000}, {0x000046, 0x000046, 0x000000}}},
+ {0x00fb01, 0, {{0x00fb01, 0x000000, 0x000000}, {0x000046, 0x000069, 0x000000}, {0x000046, 0x000049, 0x000000}}},
+ {0x00fb02, 0, {{0x00fb02, 0x000000, 0x000000}, {0x000046, 0x00006c, 0x000000}, {0x000046, 0x00004c, 0x000000}}},
+ {0x00fb03, 0, {{0x00fb03, 0x000000, 0x000000}, {0x000046, 0x000066, 0x000069}, {0x000046, 0x000046, 0x000049}}},
+ {0x00fb04, 0, {{0x00fb04, 0x000000, 0x000000}, {0x000046, 0x000066, 0x00006c}, {0x000046, 0x000046, 0x00004c}}},
+ {0x00fb05, 0, {{0x00fb05, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb06, 0, {{0x00fb06, 0x000000, 0x000000}, {0x000053, 0x000074, 0x000000}, {0x000053, 0x000054, 0x000000}}},
+ {0x00fb13, 0, {{0x00fb13, 0x000000, 0x000000}, {0x000544, 0x000576, 0x000000}, {0x000544, 0x000546, 0x000000}}},
+ {0x00fb14, 0, {{0x00fb14, 0x000000, 0x000000}, {0x000544, 0x000565, 0x000000}, {0x000544, 0x000535, 0x000000}}},
+ {0x00fb15, 0, {{0x00fb15, 0x000000, 0x000000}, {0x000544, 0x00056b, 0x000000}, {0x000544, 0x00053b, 0x000000}}},
+ {0x00fb16, 0, {{0x00fb16, 0x000000, 0x000000}, {0x00054e, 0x000576, 0x000000}, {0x00054e, 0x000546, 0x000000}}},
+ {0x00fb17, 0, {{0x00fb17, 0x000000, 0x000000}, {0x000544, 0x00056d, 0x000000}, {0x000544, 0x00053d, 0x000000}}},
+ {0, 0, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
+};
+
/*
* Case mapping table. Dense for codepoints < 0x80 (enabling fast lookup),
* sparse for higher codepoints (requiring scan or binary search).
*/
-static const pg_case_map case_map[2955] =
+static const pg_case_map case_map[3003] =
{
/* begin dense entries for codepoints < 0x80 */
- {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}},
- {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}},
- {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}},
- {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}},
- {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}},
- {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}},
- {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}},
- {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}},
- {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}},
- {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}},
- {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}},
- {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}},
- {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}},
- {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}},
- {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}},
- {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}},
- {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}},
- {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}},
- {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}},
- {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}},
- {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}},
- {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}},
- {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}},
- {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}},
- {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}},
- {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}},
- {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}},
- {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}},
- {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}},
- {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}},
- {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}},
- {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}},
- {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}},
- {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}},
- {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}},
- {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}},
- {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}},
- {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}},
- {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}},
- {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}},
- {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}},
- {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}},
- {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}},
- {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}},
- {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}},
- {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}},
- {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}},
- {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}},
- {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}},
- {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}},
- {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}},
- {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}},
- {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}},
- {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}},
- {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}},
- {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}},
- {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}},
- {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}},
- {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}},
- {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}},
- {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}},
- {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}},
- {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}},
- {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}},
- {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}},
- {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}},
- {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}},
- {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}},
- {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}},
- {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}},
- {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}},
- {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}},
- {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}},
- {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}},
- {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}},
- {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}},
- {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}},
- {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}},
- {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}},
- {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}},
- {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}},
- {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}},
- {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}},
- {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}},
- {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}},
- {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}},
- {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}},
- {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}},
- {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}},
- {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}},
- {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}},
- {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}},
- {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}},
- {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}},
- {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}},
- {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}},
- {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}},
- {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}},
- {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}},
- {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}},
+ {0x000000, {[CaseLower] = 0x000000,[CaseTitle] = 0x000000,[CaseUpper] = 0x000000}, NULL},
+ {0x000001, {[CaseLower] = 0x000001,[CaseTitle] = 0x000001,[CaseUpper] = 0x000001}, NULL},
+ {0x000002, {[CaseLower] = 0x000002,[CaseTitle] = 0x000002,[CaseUpper] = 0x000002}, NULL},
+ {0x000003, {[CaseLower] = 0x000003,[CaseTitle] = 0x000003,[CaseUpper] = 0x000003}, NULL},
+ {0x000004, {[CaseLower] = 0x000004,[CaseTitle] = 0x000004,[CaseUpper] = 0x000004}, NULL},
+ {0x000005, {[CaseLower] = 0x000005,[CaseTitle] = 0x000005,[CaseUpper] = 0x000005}, NULL},
+ {0x000006, {[CaseLower] = 0x000006,[CaseTitle] = 0x000006,[CaseUpper] = 0x000006}, NULL},
+ {0x000007, {[CaseLower] = 0x000007,[CaseTitle] = 0x000007,[CaseUpper] = 0x000007}, NULL},
+ {0x000008, {[CaseLower] = 0x000008,[CaseTitle] = 0x000008,[CaseUpper] = 0x000008}, NULL},
+ {0x000009, {[CaseLower] = 0x000009,[CaseTitle] = 0x000009,[CaseUpper] = 0x000009}, NULL},
+ {0x00000a, {[CaseLower] = 0x00000a,[CaseTitle] = 0x00000a,[CaseUpper] = 0x00000a}, NULL},
+ {0x00000b, {[CaseLower] = 0x00000b,[CaseTitle] = 0x00000b,[CaseUpper] = 0x00000b}, NULL},
+ {0x00000c, {[CaseLower] = 0x00000c,[CaseTitle] = 0x00000c,[CaseUpper] = 0x00000c}, NULL},
+ {0x00000d, {[CaseLower] = 0x00000d,[CaseTitle] = 0x00000d,[CaseUpper] = 0x00000d}, NULL},
+ {0x00000e, {[CaseLower] = 0x00000e,[CaseTitle] = 0x00000e,[CaseUpper] = 0x00000e}, NULL},
+ {0x00000f, {[CaseLower] = 0x00000f,[CaseTitle] = 0x00000f,[CaseUpper] = 0x00000f}, NULL},
+ {0x000010, {[CaseLower] = 0x000010,[CaseTitle] = 0x000010,[CaseUpper] = 0x000010}, NULL},
+ {0x000011, {[CaseLower] = 0x000011,[CaseTitle] = 0x000011,[CaseUpper] = 0x000011}, NULL},
+ {0x000012, {[CaseLower] = 0x000012,[CaseTitle] = 0x000012,[CaseUpper] = 0x000012}, NULL},
+ {0x000013, {[CaseLower] = 0x000013,[CaseTitle] = 0x000013,[CaseUpper] = 0x000013}, NULL},
+ {0x000014, {[CaseLower] = 0x000014,[CaseTitle] = 0x000014,[CaseUpper] = 0x000014}, NULL},
+ {0x000015, {[CaseLower] = 0x000015,[CaseTitle] = 0x000015,[CaseUpper] = 0x000015}, NULL},
+ {0x000016, {[CaseLower] = 0x000016,[CaseTitle] = 0x000016,[CaseUpper] = 0x000016}, NULL},
+ {0x000017, {[CaseLower] = 0x000017,[CaseTitle] = 0x000017,[CaseUpper] = 0x000017}, NULL},
+ {0x000018, {[CaseLower] = 0x000018,[CaseTitle] = 0x000018,[CaseUpper] = 0x000018}, NULL},
+ {0x000019, {[CaseLower] = 0x000019,[CaseTitle] = 0x000019,[CaseUpper] = 0x000019}, NULL},
+ {0x00001a, {[CaseLower] = 0x00001a,[CaseTitle] = 0x00001a,[CaseUpper] = 0x00001a}, NULL},
+ {0x00001b, {[CaseLower] = 0x00001b,[CaseTitle] = 0x00001b,[CaseUpper] = 0x00001b}, NULL},
+ {0x00001c, {[CaseLower] = 0x00001c,[CaseTitle] = 0x00001c,[CaseUpper] = 0x00001c}, NULL},
+ {0x00001d, {[CaseLower] = 0x00001d,[CaseTitle] = 0x00001d,[CaseUpper] = 0x00001d}, NULL},
+ {0x00001e, {[CaseLower] = 0x00001e,[CaseTitle] = 0x00001e,[CaseUpper] = 0x00001e}, NULL},
+ {0x00001f, {[CaseLower] = 0x00001f,[CaseTitle] = 0x00001f,[CaseUpper] = 0x00001f}, NULL},
+ {0x000020, {[CaseLower] = 0x000020,[CaseTitle] = 0x000020,[CaseUpper] = 0x000020}, NULL},
+ {0x000021, {[CaseLower] = 0x000021,[CaseTitle] = 0x000021,[CaseUpper] = 0x000021}, NULL},
+ {0x000022, {[CaseLower] = 0x000022,[CaseTitle] = 0x000022,[CaseUpper] = 0x000022}, NULL},
+ {0x000023, {[CaseLower] = 0x000023,[CaseTitle] = 0x000023,[CaseUpper] = 0x000023}, NULL},
+ {0x000024, {[CaseLower] = 0x000024,[CaseTitle] = 0x000024,[CaseUpper] = 0x000024}, NULL},
+ {0x000025, {[CaseLower] = 0x000025,[CaseTitle] = 0x000025,[CaseUpper] = 0x000025}, NULL},
+ {0x000026, {[CaseLower] = 0x000026,[CaseTitle] = 0x000026,[CaseUpper] = 0x000026}, NULL},
+ {0x000027, {[CaseLower] = 0x000027,[CaseTitle] = 0x000027,[CaseUpper] = 0x000027}, NULL},
+ {0x000028, {[CaseLower] = 0x000028,[CaseTitle] = 0x000028,[CaseUpper] = 0x000028}, NULL},
+ {0x000029, {[CaseLower] = 0x000029,[CaseTitle] = 0x000029,[CaseUpper] = 0x000029}, NULL},
+ {0x00002a, {[CaseLower] = 0x00002a,[CaseTitle] = 0x00002a,[CaseUpper] = 0x00002a}, NULL},
+ {0x00002b, {[CaseLower] = 0x00002b,[CaseTitle] = 0x00002b,[CaseUpper] = 0x00002b}, NULL},
+ {0x00002c, {[CaseLower] = 0x00002c,[CaseTitle] = 0x00002c,[CaseUpper] = 0x00002c}, NULL},
+ {0x00002d, {[CaseLower] = 0x00002d,[CaseTitle] = 0x00002d,[CaseUpper] = 0x00002d}, NULL},
+ {0x00002e, {[CaseLower] = 0x00002e,[CaseTitle] = 0x00002e,[CaseUpper] = 0x00002e}, NULL},
+ {0x00002f, {[CaseLower] = 0x00002f,[CaseTitle] = 0x00002f,[CaseUpper] = 0x00002f}, NULL},
+ {0x000030, {[CaseLower] = 0x000030,[CaseTitle] = 0x000030,[CaseUpper] = 0x000030}, NULL},
+ {0x000031, {[CaseLower] = 0x000031,[CaseTitle] = 0x000031,[CaseUpper] = 0x000031}, NULL},
+ {0x000032, {[CaseLower] = 0x000032,[CaseTitle] = 0x000032,[CaseUpper] = 0x000032}, NULL},
+ {0x000033, {[CaseLower] = 0x000033,[CaseTitle] = 0x000033,[CaseUpper] = 0x000033}, NULL},
+ {0x000034, {[CaseLower] = 0x000034,[CaseTitle] = 0x000034,[CaseUpper] = 0x000034}, NULL},
+ {0x000035, {[CaseLower] = 0x000035,[CaseTitle] = 0x000035,[CaseUpper] = 0x000035}, NULL},
+ {0x000036, {[CaseLower] = 0x000036,[CaseTitle] = 0x000036,[CaseUpper] = 0x000036}, NULL},
+ {0x000037, {[CaseLower] = 0x000037,[CaseTitle] = 0x000037,[CaseUpper] = 0x000037}, NULL},
+ {0x000038, {[CaseLower] = 0x000038,[CaseTitle] = 0x000038,[CaseUpper] = 0x000038}, NULL},
+ {0x000039, {[CaseLower] = 0x000039,[CaseTitle] = 0x000039,[CaseUpper] = 0x000039}, NULL},
+ {0x00003a, {[CaseLower] = 0x00003a,[CaseTitle] = 0x00003a,[CaseUpper] = 0x00003a}, NULL},
+ {0x00003b, {[CaseLower] = 0x00003b,[CaseTitle] = 0x00003b,[CaseUpper] = 0x00003b}, NULL},
+ {0x00003c, {[CaseLower] = 0x00003c,[CaseTitle] = 0x00003c,[CaseUpper] = 0x00003c}, NULL},
+ {0x00003d, {[CaseLower] = 0x00003d,[CaseTitle] = 0x00003d,[CaseUpper] = 0x00003d}, NULL},
+ {0x00003e, {[CaseLower] = 0x00003e,[CaseTitle] = 0x00003e,[CaseUpper] = 0x00003e}, NULL},
+ {0x00003f, {[CaseLower] = 0x00003f,[CaseTitle] = 0x00003f,[CaseUpper] = 0x00003f}, NULL},
+ {0x000040, {[CaseLower] = 0x000040,[CaseTitle] = 0x000040,[CaseUpper] = 0x000040}, NULL},
+ {0x000041, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000042, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000043, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000044, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000045, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000046, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000047, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000048, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000049, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00004a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00004b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00004c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00004d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00004e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00004f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000050, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000051, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000052, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000053, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000054, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000055, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000056, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000057, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000058, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000059, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00005a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00005b, {[CaseLower] = 0x00005b,[CaseTitle] = 0x00005b,[CaseUpper] = 0x00005b}, NULL},
+ {0x00005c, {[CaseLower] = 0x00005c,[CaseTitle] = 0x00005c,[CaseUpper] = 0x00005c}, NULL},
+ {0x00005d, {[CaseLower] = 0x00005d,[CaseTitle] = 0x00005d,[CaseUpper] = 0x00005d}, NULL},
+ {0x00005e, {[CaseLower] = 0x00005e,[CaseTitle] = 0x00005e,[CaseUpper] = 0x00005e}, NULL},
+ {0x00005f, {[CaseLower] = 0x00005f,[CaseTitle] = 0x00005f,[CaseUpper] = 0x00005f}, NULL},
+ {0x000060, {[CaseLower] = 0x000060,[CaseTitle] = 0x000060,[CaseUpper] = 0x000060}, NULL},
+ {0x000061, {[CaseLower] = 0x000061,[CaseTitle] = 0x000041,[CaseUpper] = 0x000041}, NULL},
+ {0x000062, {[CaseLower] = 0x000062,[CaseTitle] = 0x000042,[CaseUpper] = 0x000042}, NULL},
+ {0x000063, {[CaseLower] = 0x000063,[CaseTitle] = 0x000043,[CaseUpper] = 0x000043}, NULL},
+ {0x000064, {[CaseLower] = 0x000064,[CaseTitle] = 0x000044,[CaseUpper] = 0x000044}, NULL},
+ {0x000065, {[CaseLower] = 0x000065,[CaseTitle] = 0x000045,[CaseUpper] = 0x000045}, NULL},
+ {0x000066, {[CaseLower] = 0x000066,[CaseTitle] = 0x000046,[CaseUpper] = 0x000046}, NULL},
+ {0x000067, {[CaseLower] = 0x000067,[CaseTitle] = 0x000047,[CaseUpper] = 0x000047}, NULL},
+ {0x000068, {[CaseLower] = 0x000068,[CaseTitle] = 0x000048,[CaseUpper] = 0x000048}, NULL},
+ {0x000069, {[CaseLower] = 0x000069,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x00006a, {[CaseLower] = 0x00006a,[CaseTitle] = 0x00004a,[CaseUpper] = 0x00004a}, NULL},
+ {0x00006b, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00004b,[CaseUpper] = 0x00004b}, NULL},
+ {0x00006c, {[CaseLower] = 0x00006c,[CaseTitle] = 0x00004c,[CaseUpper] = 0x00004c}, NULL},
+ {0x00006d, {[CaseLower] = 0x00006d,[CaseTitle] = 0x00004d,[CaseUpper] = 0x00004d}, NULL},
+ {0x00006e, {[CaseLower] = 0x00006e,[CaseTitle] = 0x00004e,[CaseUpper] = 0x00004e}, NULL},
+ {0x00006f, {[CaseLower] = 0x00006f,[CaseTitle] = 0x00004f,[CaseUpper] = 0x00004f}, NULL},
+ {0x000070, {[CaseLower] = 0x000070,[CaseTitle] = 0x000050,[CaseUpper] = 0x000050}, NULL},
+ {0x000071, {[CaseLower] = 0x000071,[CaseTitle] = 0x000051,[CaseUpper] = 0x000051}, NULL},
+ {0x000072, {[CaseLower] = 0x000072,[CaseTitle] = 0x000052,[CaseUpper] = 0x000052}, NULL},
+ {0x000073, {[CaseLower] = 0x000073,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000074, {[CaseLower] = 0x000074,[CaseTitle] = 0x000054,[CaseUpper] = 0x000054}, NULL},
+ {0x000075, {[CaseLower] = 0x000075,[CaseTitle] = 0x000055,[CaseUpper] = 0x000055}, NULL},
+ {0x000076, {[CaseLower] = 0x000076,[CaseTitle] = 0x000056,[CaseUpper] = 0x000056}, NULL},
+ {0x000077, {[CaseLower] = 0x000077,[CaseTitle] = 0x000057,[CaseUpper] = 0x000057}, NULL},
+ {0x000078, {[CaseLower] = 0x000078,[CaseTitle] = 0x000058,[CaseUpper] = 0x000058}, NULL},
+ {0x000079, {[CaseLower] = 0x000079,[CaseTitle] = 0x000059,[CaseUpper] = 0x000059}, NULL},
+ {0x00007a, {[CaseLower] = 0x00007a,[CaseTitle] = 0x00005a,[CaseUpper] = 0x00005a}, NULL},
+ {0x00007b, {[CaseLower] = 0x00007b,[CaseTitle] = 0x00007b,[CaseUpper] = 0x00007b}, NULL},
+ {0x00007c, {[CaseLower] = 0x00007c,[CaseTitle] = 0x00007c,[CaseUpper] = 0x00007c}, NULL},
+ {0x00007d, {[CaseLower] = 0x00007d,[CaseTitle] = 0x00007d,[CaseUpper] = 0x00007d}, NULL},
+ {0x00007e, {[CaseLower] = 0x00007e,[CaseTitle] = 0x00007e,[CaseUpper] = 0x00007e}, NULL},
+ {0x00007f, {[CaseLower] = 0x00007f,[CaseTitle] = 0x00007f,[CaseUpper] = 0x00007f}, NULL},
/* begin sparse entries for codepoints >= 0x80 */
- {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}},
- {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}},
- {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}},
- {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}},
- {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}},
- {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}},
- {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}},
- {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}},
- {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}},
- {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}},
- {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}},
- {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}},
- {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}},
- {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}},
- {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}},
- {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}},
- {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}},
- {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}},
- {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}},
- {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}},
- {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}},
- {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}},
- {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}},
- {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}},
- {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}},
- {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}},
- {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}},
- {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}},
- {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}},
- {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}},
- {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}},
- {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}},
- {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}},
- {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}},
- {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}},
- {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}},
- {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}},
- {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}},
- {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}},
- {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}},
- {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}},
- {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}},
- {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}},
- {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}},
- {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}},
- {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}},
- {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}},
- {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}},
- {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}},
- {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}},
- {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}},
- {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}},
- {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}},
- {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}},
- {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}},
- {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}},
- {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}},
- {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}},
- {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}},
- {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}},
- {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}},
- {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}},
- {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}},
- {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}},
- {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}},
- {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}},
- {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}},
- {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}},
- {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}},
- {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}},
- {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}},
- {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}},
- {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}},
- {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}},
- {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}},
- {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}},
- {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}},
- {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}},
- {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}},
- {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}},
- {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}},
- {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}},
- {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}},
- {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}},
- {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}},
- {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}},
- {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}},
- {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}},
- {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}},
- {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}},
- {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}},
- {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}},
- {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}},
- {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}},
- {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}},
- {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}},
- {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}},
- {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}},
- {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}},
- {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}},
- {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}},
- {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}},
- {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}},
- {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}},
- {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}},
- {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}},
- {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}},
- {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}},
- {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}},
- {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}},
- {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}},
- {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}},
- {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}},
- {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}},
- {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}},
- {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}},
- {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}},
- {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}},
- {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}},
- {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}},
- {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}},
- {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}},
- {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}},
- {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}},
- {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}},
- {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}},
- {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}},
- {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}},
- {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}},
- {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}},
- {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}},
- {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}},
- {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}},
- {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}},
- {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}},
- {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}},
- {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}},
- {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}},
- {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}},
- {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}},
- {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}},
- {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}},
- {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}},
- {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}},
- {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}},
- {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}},
- {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}},
- {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}},
- {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}},
- {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}},
- {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}},
- {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}},
- {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}},
- {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}},
- {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}},
- {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}},
- {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}},
- {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}},
- {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}},
- {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}},
- {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}},
- {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}},
- {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}},
- {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}},
- {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}},
- {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}},
- {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}},
- {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}},
- {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}},
- {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}},
- {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}},
- {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}},
- {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}},
- {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}},
- {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}},
- {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}},
- {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}},
- {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}},
- {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}},
- {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}},
- {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}},
- {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}},
- {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}},
- {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}},
- {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}},
- {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}},
- {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}},
- {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}},
- {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}},
- {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}},
- {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}},
- {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}},
- {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}},
- {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}},
- {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}},
- {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}},
- {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}},
- {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}},
- {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}},
- {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}},
- {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}},
- {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}},
- {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}},
- {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}},
- {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}},
- {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}},
- {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}},
- {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}},
- {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}},
- {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}},
- {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}},
- {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}},
- {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}},
- {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}},
- {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}},
- {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}},
- {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}},
- {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}},
- {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}},
- {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}},
- {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}},
- {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}},
- {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}},
- {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}},
- {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}},
- {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}},
- {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}},
- {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}},
- {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}},
- {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}},
- {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}},
- {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}},
- {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}},
- {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}},
- {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}},
- {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}},
- {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}},
- {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}},
- {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}},
- {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}},
- {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}},
- {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}},
- {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}},
- {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}},
- {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}},
- {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}},
- {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}},
- {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}},
- {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}},
- {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}},
- {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}},
- {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}},
- {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}},
- {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}},
- {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}},
- {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}},
- {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}},
- {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}},
- {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}},
- {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}},
- {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}},
- {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}},
- {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}},
- {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}},
- {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}},
- {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}},
- {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}},
- {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}},
- {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}},
- {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}},
- {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}},
- {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}},
- {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}},
- {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}},
- {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}},
- {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}},
- {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}},
- {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}},
- {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}},
- {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}},
- {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}},
- {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}},
- {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}},
- {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}},
- {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}},
- {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}},
- {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}},
- {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}},
- {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}},
- {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}},
- {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}},
- {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}},
- {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}},
- {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}},
- {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}},
- {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}},
- {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}},
- {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}},
- {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}},
- {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}},
- {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}},
- {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}},
- {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}},
- {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}},
- {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}},
- {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}},
- {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}},
- {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}},
- {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}},
- {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}},
- {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}},
- {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}},
- {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}},
- {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}},
- {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}},
- {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}},
- {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}},
- {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}},
- {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}},
- {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}},
- {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}},
- {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}},
- {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}},
- {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}},
- {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}},
- {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}},
- {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}},
- {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}},
- {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}},
- {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}},
- {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}},
- {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}},
- {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}},
- {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}},
- {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}},
- {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}},
- {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}},
- {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}},
- {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}},
- {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}},
- {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}},
- {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}},
- {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}},
- {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}},
- {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}},
- {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}},
- {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}},
- {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}},
- {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}},
- {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}},
- {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}},
- {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}},
- {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}},
- {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}},
- {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}},
- {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}},
- {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}},
- {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}},
- {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}},
- {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}},
- {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}},
- {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}},
- {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}},
- {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}},
- {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}},
- {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}},
- {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}},
- {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}},
- {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}},
- {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}},
- {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}},
- {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}},
- {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}},
- {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}},
- {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}},
- {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}},
- {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}},
- {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}},
- {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}},
- {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}},
- {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}},
- {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}},
- {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}},
- {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}},
- {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}},
- {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}},
- {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}},
- {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}},
- {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}},
- {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}},
- {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}},
- {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}},
- {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}},
- {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}},
- {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}},
- {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}},
- {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}},
- {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}},
- {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}},
- {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}},
- {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}},
- {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}},
- {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}},
- {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}},
- {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}},
- {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}},
- {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}},
- {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}},
- {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}},
- {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}},
- {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}},
- {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}},
- {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}},
- {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}},
- {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}},
- {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}},
- {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}},
- {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}},
- {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}},
- {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}},
- {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}},
- {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}},
- {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}},
- {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}},
- {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}},
- {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}},
- {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}},
- {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}},
- {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}},
- {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}},
- {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}},
- {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}},
- {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}},
- {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}},
- {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}},
- {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}},
- {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}},
- {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}},
- {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}},
- {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}},
- {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}},
- {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}},
- {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}},
- {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}},
- {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}},
- {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}},
- {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}},
- {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}},
- {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}},
- {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}},
- {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}},
- {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}},
- {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}},
- {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}},
- {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}},
- {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}},
- {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}},
- {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}},
- {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}},
- {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}},
- {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}},
- {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}},
- {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}},
- {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}},
- {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}},
- {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}},
- {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}},
- {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}},
- {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}},
- {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}},
- {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}},
- {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}},
- {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}},
- {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}},
- {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}},
- {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}},
- {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}},
- {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}},
- {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}},
- {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}},
- {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}},
- {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}},
- {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}},
- {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}},
- {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}},
- {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}},
- {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}},
- {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}},
- {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}},
- {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}},
- {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}},
- {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}},
- {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}},
- {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}},
- {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}},
- {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}},
- {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}},
- {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}},
- {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}},
- {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}},
- {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}},
- {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}},
- {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}},
- {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}},
- {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}},
- {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}},
- {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}},
- {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}},
- {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}},
- {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}},
- {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}},
- {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}},
- {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}},
- {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}},
- {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}},
- {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}},
- {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}},
- {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}},
- {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}},
- {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}},
- {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}},
- {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}},
- {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}},
- {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}},
- {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}},
- {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}},
- {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}},
- {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}},
- {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}},
- {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}},
- {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}},
- {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}},
- {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}},
- {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}},
- {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}},
- {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}},
- {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}},
- {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}},
- {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}},
- {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}},
- {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}},
- {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}},
- {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}},
- {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}},
- {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}},
- {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}},
- {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}},
- {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}},
- {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}},
- {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}},
- {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}},
- {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}},
- {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}},
- {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}},
- {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}},
- {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}},
- {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}},
- {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}},
- {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}},
- {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}},
- {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}},
- {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}},
- {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}},
- {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}},
- {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}},
- {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}},
- {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}},
- {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}},
- {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}},
- {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}},
- {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}},
- {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}},
- {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}},
- {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}},
- {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}},
- {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}},
- {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}},
- {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}},
- {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}},
- {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}},
- {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}},
- {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}},
- {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}},
- {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}},
- {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}},
- {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}},
- {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}},
- {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}},
- {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}},
- {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}},
- {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}},
- {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}},
- {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}},
- {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}},
- {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}},
- {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}},
- {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}},
- {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}},
- {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}},
- {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}},
- {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}},
- {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}},
- {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}},
- {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}},
- {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}},
- {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}},
- {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}},
- {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}},
- {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}},
- {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}},
- {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}},
- {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}},
- {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}},
- {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}},
- {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}},
- {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}},
- {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}},
- {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}},
- {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}},
- {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}},
- {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}},
- {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}},
- {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}},
- {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}},
- {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}},
- {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}},
- {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}},
- {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}},
- {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}},
- {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}},
- {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}},
- {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}},
- {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}},
- {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}},
- {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}},
- {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}},
- {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}},
- {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}},
- {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}},
- {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}},
- {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}},
- {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}},
- {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}},
- {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}},
- {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}},
- {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}},
- {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}},
- {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}},
- {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}},
- {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}},
- {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}},
- {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}},
- {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}},
- {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}},
- {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}},
- {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}},
- {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}},
- {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}},
- {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}},
- {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}},
- {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}},
- {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}},
- {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}},
- {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}},
- {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}},
- {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}},
- {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}},
- {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}},
- {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}},
- {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}},
- {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}},
- {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}},
- {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}},
- {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}},
- {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}},
- {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}},
- {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}},
- {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}},
- {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}},
- {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}},
- {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}},
- {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}},
- {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}},
- {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}},
- {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}},
- {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}},
- {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}},
- {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}},
- {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}},
- {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}},
- {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}},
- {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}},
- {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}},
- {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}},
- {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}},
- {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}},
- {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}},
- {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}},
- {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}},
- {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}},
- {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}},
- {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}},
- {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}},
- {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}},
- {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}},
- {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}},
- {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}},
- {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}},
- {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}},
- {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}},
- {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}},
- {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}},
- {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}},
- {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}},
- {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}},
- {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}},
- {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}},
- {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}},
- {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}},
- {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}},
- {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}},
- {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}},
- {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}},
- {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}},
- {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}},
- {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}},
- {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}},
- {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}},
- {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}},
- {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}},
- {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}},
- {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}},
- {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}},
- {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}},
- {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}},
- {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}},
- {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}},
- {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}},
- {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}},
- {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}},
- {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}},
- {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}},
- {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}},
- {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}},
- {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}},
- {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}},
- {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}},
- {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}},
- {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}},
- {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}},
- {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}},
- {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}},
- {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}},
- {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}},
- {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}},
- {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}},
- {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}},
- {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}},
- {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}},
- {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}},
- {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}},
- {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}},
- {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}},
- {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}},
- {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}},
- {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}},
- {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}},
- {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}},
- {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}},
- {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}},
- {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}},
- {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}},
- {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}},
- {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}},
- {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}},
- {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}},
- {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}},
- {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}},
- {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}},
- {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}},
- {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}},
- {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}},
- {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}},
- {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}},
- {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}},
- {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}},
- {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}},
- {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}},
- {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}},
- {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}},
- {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}},
- {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}},
- {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}},
- {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}},
- {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}},
- {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}},
- {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}},
- {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}},
- {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}},
- {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}},
- {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}},
- {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}},
- {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}},
- {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}},
- {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}},
- {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}},
- {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}},
- {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}},
- {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}},
- {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}},
- {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}},
- {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}},
- {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}},
- {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}},
- {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}},
- {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}},
- {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}},
- {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}},
- {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}},
- {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}},
- {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}},
- {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}},
- {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}},
- {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}},
- {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}},
- {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}},
- {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}},
- {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}},
- {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}},
- {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}},
- {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}},
- {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}},
- {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}},
- {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}},
- {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}},
- {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}},
- {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}},
- {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}},
- {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}},
- {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}},
- {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}},
- {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}},
- {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}},
- {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}},
- {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}},
- {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}},
- {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}},
- {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}},
- {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}},
- {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}},
- {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}},
- {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}},
- {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}},
- {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}},
- {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}},
- {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}},
- {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}},
- {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}},
- {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}},
- {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}},
- {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}},
- {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}},
- {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}},
- {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}},
- {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}},
- {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}},
- {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}},
- {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}},
- {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}},
- {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}},
- {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}},
- {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}},
- {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}},
- {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}},
- {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}},
- {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}},
- {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}},
- {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}},
- {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}},
- {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}},
- {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}},
- {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}},
- {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}},
- {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}},
- {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}},
- {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}},
- {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}},
- {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}},
- {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}},
- {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}},
- {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}},
- {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}},
- {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}},
- {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}},
- {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}},
- {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}},
- {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}},
- {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}},
- {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}},
- {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}},
- {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}},
- {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}},
- {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}},
- {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}},
- {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}},
- {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}},
- {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}},
- {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}},
- {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}},
- {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}},
- {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}},
- {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}},
- {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}},
- {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}},
- {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}},
- {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}},
- {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}},
- {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}},
- {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}},
- {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}},
- {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}},
- {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}},
- {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}},
- {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}},
- {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}},
- {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}},
- {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}},
- {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}},
- {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}},
- {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}},
- {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}},
- {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}},
- {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}},
- {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}},
- {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}},
- {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}},
- {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}},
- {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}},
- {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}},
- {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}},
- {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}},
- {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}},
- {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}},
- {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}},
- {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}},
- {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}},
- {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}},
- {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}},
- {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}},
- {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}},
- {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}},
- {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}},
- {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}},
- {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}},
- {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}},
- {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}},
- {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}},
- {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}},
- {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}},
- {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}},
- {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}},
- {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}},
- {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}},
- {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}},
- {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}},
- {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}},
- {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}},
- {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}},
- {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}},
- {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}},
- {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}},
- {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}},
- {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}},
- {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}},
- {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}},
- {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}},
- {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}},
- {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}},
- {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}},
- {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}},
- {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}},
- {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}},
- {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}},
- {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}},
- {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}},
- {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}},
- {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}},
- {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}},
- {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}},
- {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}},
- {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}},
- {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}},
- {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}},
- {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}},
- {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}},
- {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}},
- {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}},
- {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}},
- {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}},
- {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}},
- {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}},
- {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}},
- {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}},
- {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}},
- {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}},
- {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}},
- {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}},
- {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}},
- {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}},
- {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}},
- {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}},
- {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}},
- {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}},
- {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}},
- {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}},
- {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}},
- {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}},
- {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}},
- {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}},
- {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}},
- {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}},
- {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}},
- {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}},
- {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}},
- {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}},
- {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}},
- {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}},
- {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}},
- {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}},
- {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}},
- {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}},
- {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}},
- {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}},
- {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}},
- {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}},
- {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}},
- {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}},
- {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}},
- {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}},
- {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}},
- {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}},
- {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}},
- {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}},
- {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}},
- {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}},
- {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}},
- {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}},
- {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}},
- {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}},
- {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}},
- {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}},
- {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}},
- {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}},
- {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}},
- {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}},
- {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}},
- {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}},
- {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}},
- {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}},
- {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}},
- {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}},
- {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}},
- {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}},
- {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}},
- {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}},
- {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}},
- {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}},
- {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}},
- {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}},
- {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}},
- {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}},
- {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}},
- {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}},
- {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}},
- {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}},
- {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}},
- {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}},
- {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}},
- {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}},
- {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}},
- {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}},
- {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}},
- {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}},
- {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}},
- {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}},
- {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}},
- {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}},
- {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}},
- {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}},
- {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}},
- {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}},
- {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}},
- {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}},
- {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}},
- {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}},
- {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}},
- {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}},
- {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}},
- {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}},
- {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}},
- {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}},
- {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}},
- {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}},
- {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}},
- {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}},
- {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}},
- {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}},
- {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}},
- {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}},
- {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}},
- {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}},
- {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}},
- {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}},
- {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}},
- {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}},
- {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}},
- {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}},
- {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}},
- {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}},
- {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}},
- {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}},
- {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}},
- {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}},
- {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}},
- {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}},
- {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}},
- {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}},
- {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}},
- {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}},
- {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}},
- {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}},
- {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}},
- {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}},
- {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}},
- {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}},
- {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}},
- {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}},
- {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}},
- {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}},
- {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}},
- {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}},
- {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}},
- {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}},
- {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}},
- {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}},
- {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}},
- {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}},
- {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}},
- {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}},
- {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}},
- {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}},
- {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}},
- {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}},
- {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}},
- {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}},
- {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}},
- {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}},
- {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}},
- {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}},
- {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}},
- {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}},
- {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}},
- {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}},
- {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}},
- {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}},
- {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}},
- {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}},
- {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}},
- {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}},
- {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}},
- {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}},
- {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}},
- {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}},
- {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}},
- {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}},
- {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}},
- {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}},
- {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}},
- {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}},
- {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}},
- {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}},
- {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}},
- {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}},
- {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}},
- {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}},
- {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}},
- {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}},
- {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}},
- {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}},
- {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}},
- {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}},
- {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}},
- {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}},
- {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}},
- {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}},
- {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}},
- {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}},
- {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}},
- {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}},
- {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}},
- {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}},
- {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}},
- {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}},
- {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}},
- {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}},
- {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}},
- {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}},
- {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}},
- {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}},
- {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}},
- {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}},
- {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}},
- {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}},
- {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}},
- {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}},
- {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}},
- {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}},
- {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}},
- {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}},
- {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}},
- {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}},
- {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}},
- {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}},
- {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}},
- {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}},
- {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}},
- {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}},
- {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}},
- {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}},
- {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}},
- {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}},
- {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}},
- {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}},
- {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}},
- {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}},
- {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}},
- {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}},
- {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}},
- {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}},
- {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}},
- {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}},
- {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}},
- {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}},
- {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}},
- {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}},
- {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}},
- {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}},
- {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}},
- {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}},
- {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}},
- {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}},
- {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}},
- {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}},
- {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}},
- {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}},
- {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}},
- {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}},
- {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}},
- {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}},
- {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}},
- {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}},
- {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}},
- {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}},
- {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}},
- {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}},
- {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}},
- {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}},
- {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}},
- {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}},
- {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}},
- {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}},
- {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}},
- {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}},
- {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}},
- {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}},
- {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}},
- {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}},
- {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}},
- {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}},
- {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}},
- {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}},
- {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}},
- {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}},
- {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}},
- {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}},
- {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}},
- {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}},
- {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}},
- {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}},
- {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}},
- {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}},
- {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}},
- {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}},
- {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}},
- {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}},
- {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}},
- {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}},
- {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}},
- {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}},
- {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}},
- {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}},
- {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}},
- {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}},
- {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}},
- {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}},
- {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}},
- {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}},
- {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}},
- {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}},
- {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}},
- {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}},
- {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}},
- {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}},
- {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}},
- {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}},
- {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}},
- {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}},
- {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}},
- {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}},
- {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}},
- {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}},
- {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}},
- {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}},
- {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}},
- {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}},
- {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}},
- {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}},
- {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}},
- {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}},
- {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}},
- {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}},
- {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}},
- {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}},
- {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}},
- {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}},
- {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}},
- {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}},
- {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}},
- {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}},
- {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}},
- {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}},
- {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}},
- {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}},
- {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}},
- {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}},
- {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}},
- {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}},
- {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}},
- {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}},
- {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}},
- {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}},
- {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}},
- {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}},
- {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}},
- {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}},
- {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}},
- {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}},
- {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}},
- {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}},
- {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}},
- {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}},
- {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}},
- {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}},
- {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}},
- {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}},
- {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}},
- {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}},
- {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}},
- {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}},
- {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}},
- {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}},
- {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}},
- {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}},
- {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}},
- {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}},
- {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}},
- {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}},
- {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}},
- {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}},
- {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}},
- {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}},
- {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}},
- {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}},
- {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}},
- {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}},
- {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}},
- {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}},
- {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}},
- {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}},
- {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}},
- {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}},
- {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}},
- {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}},
- {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}},
- {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}},
- {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}},
- {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}},
- {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}},
- {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}},
- {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}},
- {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}},
- {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}},
- {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}},
- {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}},
- {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}},
- {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}},
- {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}},
- {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}},
- {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}},
- {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}},
- {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}},
- {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}},
- {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}},
- {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}},
- {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}},
- {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}},
- {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}},
- {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
- {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}},
- {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}},
- {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}},
- {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}},
- {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}},
- {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}},
- {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}},
- {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}},
- {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}},
- {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}},
- {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}},
- {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}},
- {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}},
- {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}},
- {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}},
- {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}},
- {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}},
- {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}},
- {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}},
- {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}},
- {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}},
- {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}},
- {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}},
- {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}},
- {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}},
- {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}},
- {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}},
- {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}},
- {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}},
- {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}},
- {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}},
- {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}},
- {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}},
- {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}},
+ {0x0000b5, {[CaseLower] = 0x0000b5,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0000c0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000c1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000c2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000c3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000c4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000c5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000c6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000c7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000c8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000c9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ca, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000cb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000cc, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000cd, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ce, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000cf, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000d0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000d1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000d2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000d3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000d4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000d5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000d6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000d8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000d9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000da, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000db, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000dc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000dd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000de, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000df, {[CaseLower] = 0x0000df,[CaseTitle] = 0x0000df,[CaseUpper] = 0x0000df}, &special_case[0]},
+ {0x0000e0, {[CaseLower] = 0x0000e0,[CaseTitle] = 0x0000c0,[CaseUpper] = 0x0000c0}, NULL},
+ {0x0000e1, {[CaseLower] = 0x0000e1,[CaseTitle] = 0x0000c1,[CaseUpper] = 0x0000c1}, NULL},
+ {0x0000e2, {[CaseLower] = 0x0000e2,[CaseTitle] = 0x0000c2,[CaseUpper] = 0x0000c2}, NULL},
+ {0x0000e3, {[CaseLower] = 0x0000e3,[CaseTitle] = 0x0000c3,[CaseUpper] = 0x0000c3}, NULL},
+ {0x0000e4, {[CaseLower] = 0x0000e4,[CaseTitle] = 0x0000c4,[CaseUpper] = 0x0000c4}, NULL},
+ {0x0000e5, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x0000c5,[CaseUpper] = 0x0000c5}, NULL},
+ {0x0000e6, {[CaseLower] = 0x0000e6,[CaseTitle] = 0x0000c6,[CaseUpper] = 0x0000c6}, NULL},
+ {0x0000e7, {[CaseLower] = 0x0000e7,[CaseTitle] = 0x0000c7,[CaseUpper] = 0x0000c7}, NULL},
+ {0x0000e8, {[CaseLower] = 0x0000e8,[CaseTitle] = 0x0000c8,[CaseUpper] = 0x0000c8}, NULL},
+ {0x0000e9, {[CaseLower] = 0x0000e9,[CaseTitle] = 0x0000c9,[CaseUpper] = 0x0000c9}, NULL},
+ {0x0000ea, {[CaseLower] = 0x0000ea,[CaseTitle] = 0x0000ca,[CaseUpper] = 0x0000ca}, NULL},
+ {0x0000eb, {[CaseLower] = 0x0000eb,[CaseTitle] = 0x0000cb,[CaseUpper] = 0x0000cb}, NULL},
+ {0x0000ec, {[CaseLower] = 0x0000ec,[CaseTitle] = 0x0000cc,[CaseUpper] = 0x0000cc}, NULL},
+ {0x0000ed, {[CaseLower] = 0x0000ed,[CaseTitle] = 0x0000cd,[CaseUpper] = 0x0000cd}, NULL},
+ {0x0000ee, {[CaseLower] = 0x0000ee,[CaseTitle] = 0x0000ce,[CaseUpper] = 0x0000ce}, NULL},
+ {0x0000ef, {[CaseLower] = 0x0000ef,[CaseTitle] = 0x0000cf,[CaseUpper] = 0x0000cf}, NULL},
+ {0x0000f0, {[CaseLower] = 0x0000f0,[CaseTitle] = 0x0000d0,[CaseUpper] = 0x0000d0}, NULL},
+ {0x0000f1, {[CaseLower] = 0x0000f1,[CaseTitle] = 0x0000d1,[CaseUpper] = 0x0000d1}, NULL},
+ {0x0000f2, {[CaseLower] = 0x0000f2,[CaseTitle] = 0x0000d2,[CaseUpper] = 0x0000d2}, NULL},
+ {0x0000f3, {[CaseLower] = 0x0000f3,[CaseTitle] = 0x0000d3,[CaseUpper] = 0x0000d3}, NULL},
+ {0x0000f4, {[CaseLower] = 0x0000f4,[CaseTitle] = 0x0000d4,[CaseUpper] = 0x0000d4}, NULL},
+ {0x0000f5, {[CaseLower] = 0x0000f5,[CaseTitle] = 0x0000d5,[CaseUpper] = 0x0000d5}, NULL},
+ {0x0000f6, {[CaseLower] = 0x0000f6,[CaseTitle] = 0x0000d6,[CaseUpper] = 0x0000d6}, NULL},
+ {0x0000f8, {[CaseLower] = 0x0000f8,[CaseTitle] = 0x0000d8,[CaseUpper] = 0x0000d8}, NULL},
+ {0x0000f9, {[CaseLower] = 0x0000f9,[CaseTitle] = 0x0000d9,[CaseUpper] = 0x0000d9}, NULL},
+ {0x0000fa, {[CaseLower] = 0x0000fa,[CaseTitle] = 0x0000da,[CaseUpper] = 0x0000da}, NULL},
+ {0x0000fb, {[CaseLower] = 0x0000fb,[CaseTitle] = 0x0000db,[CaseUpper] = 0x0000db}, NULL},
+ {0x0000fc, {[CaseLower] = 0x0000fc,[CaseTitle] = 0x0000dc,[CaseUpper] = 0x0000dc}, NULL},
+ {0x0000fd, {[CaseLower] = 0x0000fd,[CaseTitle] = 0x0000dd,[CaseUpper] = 0x0000dd}, NULL},
+ {0x0000fe, {[CaseLower] = 0x0000fe,[CaseTitle] = 0x0000de,[CaseUpper] = 0x0000de}, NULL},
+ {0x0000ff, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000100, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000101, {[CaseLower] = 0x000101,[CaseTitle] = 0x000100,[CaseUpper] = 0x000100}, NULL},
+ {0x000102, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000103, {[CaseLower] = 0x000103,[CaseTitle] = 0x000102,[CaseUpper] = 0x000102}, NULL},
+ {0x000104, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000105, {[CaseLower] = 0x000105,[CaseTitle] = 0x000104,[CaseUpper] = 0x000104}, NULL},
+ {0x000106, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000107, {[CaseLower] = 0x000107,[CaseTitle] = 0x000106,[CaseUpper] = 0x000106}, NULL},
+ {0x000108, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x000109, {[CaseLower] = 0x000109,[CaseTitle] = 0x000108,[CaseUpper] = 0x000108}, NULL},
+ {0x00010a, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010b, {[CaseLower] = 0x00010b,[CaseTitle] = 0x00010a,[CaseUpper] = 0x00010a}, NULL},
+ {0x00010c, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010d, {[CaseLower] = 0x00010d,[CaseTitle] = 0x00010c,[CaseUpper] = 0x00010c}, NULL},
+ {0x00010e, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x00010f, {[CaseLower] = 0x00010f,[CaseTitle] = 0x00010e,[CaseUpper] = 0x00010e}, NULL},
+ {0x000110, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000111, {[CaseLower] = 0x000111,[CaseTitle] = 0x000110,[CaseUpper] = 0x000110}, NULL},
+ {0x000112, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000113, {[CaseLower] = 0x000113,[CaseTitle] = 0x000112,[CaseUpper] = 0x000112}, NULL},
+ {0x000114, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000115, {[CaseLower] = 0x000115,[CaseTitle] = 0x000114,[CaseUpper] = 0x000114}, NULL},
+ {0x000116, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000117, {[CaseLower] = 0x000117,[CaseTitle] = 0x000116,[CaseUpper] = 0x000116}, NULL},
+ {0x000118, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x000119, {[CaseLower] = 0x000119,[CaseTitle] = 0x000118,[CaseUpper] = 0x000118}, NULL},
+ {0x00011a, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011b, {[CaseLower] = 0x00011b,[CaseTitle] = 0x00011a,[CaseUpper] = 0x00011a}, NULL},
+ {0x00011c, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011d, {[CaseLower] = 0x00011d,[CaseTitle] = 0x00011c,[CaseUpper] = 0x00011c}, NULL},
+ {0x00011e, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x00011f, {[CaseLower] = 0x00011f,[CaseTitle] = 0x00011e,[CaseUpper] = 0x00011e}, NULL},
+ {0x000120, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000121, {[CaseLower] = 0x000121,[CaseTitle] = 0x000120,[CaseUpper] = 0x000120}, NULL},
+ {0x000122, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000123, {[CaseLower] = 0x000123,[CaseTitle] = 0x000122,[CaseUpper] = 0x000122}, NULL},
+ {0x000124, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000125, {[CaseLower] = 0x000125,[CaseTitle] = 0x000124,[CaseUpper] = 0x000124}, NULL},
+ {0x000126, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000127, {[CaseLower] = 0x000127,[CaseTitle] = 0x000126,[CaseUpper] = 0x000126}, NULL},
+ {0x000128, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x000129, {[CaseLower] = 0x000129,[CaseTitle] = 0x000128,[CaseUpper] = 0x000128}, NULL},
+ {0x00012a, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012b, {[CaseLower] = 0x00012b,[CaseTitle] = 0x00012a,[CaseUpper] = 0x00012a}, NULL},
+ {0x00012c, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012d, {[CaseLower] = 0x00012d,[CaseTitle] = 0x00012c,[CaseUpper] = 0x00012c}, NULL},
+ {0x00012e, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x00012f, {[CaseLower] = 0x00012f,[CaseTitle] = 0x00012e,[CaseUpper] = 0x00012e}, NULL},
+ {0x000130, {[CaseLower] = 0x000069,[CaseTitle] = 0x000130,[CaseUpper] = 0x000130}, &special_case[1]},
+ {0x000131, {[CaseLower] = 0x000131,[CaseTitle] = 0x000049,[CaseUpper] = 0x000049}, NULL},
+ {0x000132, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000133, {[CaseLower] = 0x000133,[CaseTitle] = 0x000132,[CaseUpper] = 0x000132}, NULL},
+ {0x000134, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000135, {[CaseLower] = 0x000135,[CaseTitle] = 0x000134,[CaseUpper] = 0x000134}, NULL},
+ {0x000136, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000137, {[CaseLower] = 0x000137,[CaseTitle] = 0x000136,[CaseUpper] = 0x000136}, NULL},
+ {0x000139, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013a, {[CaseLower] = 0x00013a,[CaseTitle] = 0x000139,[CaseUpper] = 0x000139}, NULL},
+ {0x00013b, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013c, {[CaseLower] = 0x00013c,[CaseTitle] = 0x00013b,[CaseUpper] = 0x00013b}, NULL},
+ {0x00013d, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013e, {[CaseLower] = 0x00013e,[CaseTitle] = 0x00013d,[CaseUpper] = 0x00013d}, NULL},
+ {0x00013f, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000140, {[CaseLower] = 0x000140,[CaseTitle] = 0x00013f,[CaseUpper] = 0x00013f}, NULL},
+ {0x000141, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000142, {[CaseLower] = 0x000142,[CaseTitle] = 0x000141,[CaseUpper] = 0x000141}, NULL},
+ {0x000143, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000144, {[CaseLower] = 0x000144,[CaseTitle] = 0x000143,[CaseUpper] = 0x000143}, NULL},
+ {0x000145, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000146, {[CaseLower] = 0x000146,[CaseTitle] = 0x000145,[CaseUpper] = 0x000145}, NULL},
+ {0x000147, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000148, {[CaseLower] = 0x000148,[CaseTitle] = 0x000147,[CaseUpper] = 0x000147}, NULL},
+ {0x000149, {[CaseLower] = 0x000149,[CaseTitle] = 0x000149,[CaseUpper] = 0x000149}, &special_case[2]},
+ {0x00014a, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014b, {[CaseLower] = 0x00014b,[CaseTitle] = 0x00014a,[CaseUpper] = 0x00014a}, NULL},
+ {0x00014c, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014d, {[CaseLower] = 0x00014d,[CaseTitle] = 0x00014c,[CaseUpper] = 0x00014c}, NULL},
+ {0x00014e, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x00014f, {[CaseLower] = 0x00014f,[CaseTitle] = 0x00014e,[CaseUpper] = 0x00014e}, NULL},
+ {0x000150, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000151, {[CaseLower] = 0x000151,[CaseTitle] = 0x000150,[CaseUpper] = 0x000150}, NULL},
+ {0x000152, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000153, {[CaseLower] = 0x000153,[CaseTitle] = 0x000152,[CaseUpper] = 0x000152}, NULL},
+ {0x000154, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000155, {[CaseLower] = 0x000155,[CaseTitle] = 0x000154,[CaseUpper] = 0x000154}, NULL},
+ {0x000156, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000157, {[CaseLower] = 0x000157,[CaseTitle] = 0x000156,[CaseUpper] = 0x000156}, NULL},
+ {0x000158, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x000159, {[CaseLower] = 0x000159,[CaseTitle] = 0x000158,[CaseUpper] = 0x000158}, NULL},
+ {0x00015a, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015b, {[CaseLower] = 0x00015b,[CaseTitle] = 0x00015a,[CaseUpper] = 0x00015a}, NULL},
+ {0x00015c, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015d, {[CaseLower] = 0x00015d,[CaseTitle] = 0x00015c,[CaseUpper] = 0x00015c}, NULL},
+ {0x00015e, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x00015f, {[CaseLower] = 0x00015f,[CaseTitle] = 0x00015e,[CaseUpper] = 0x00015e}, NULL},
+ {0x000160, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000161, {[CaseLower] = 0x000161,[CaseTitle] = 0x000160,[CaseUpper] = 0x000160}, NULL},
+ {0x000162, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000163, {[CaseLower] = 0x000163,[CaseTitle] = 0x000162,[CaseUpper] = 0x000162}, NULL},
+ {0x000164, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000165, {[CaseLower] = 0x000165,[CaseTitle] = 0x000164,[CaseUpper] = 0x000164}, NULL},
+ {0x000166, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000167, {[CaseLower] = 0x000167,[CaseTitle] = 0x000166,[CaseUpper] = 0x000166}, NULL},
+ {0x000168, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x000169, {[CaseLower] = 0x000169,[CaseTitle] = 0x000168,[CaseUpper] = 0x000168}, NULL},
+ {0x00016a, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016b, {[CaseLower] = 0x00016b,[CaseTitle] = 0x00016a,[CaseUpper] = 0x00016a}, NULL},
+ {0x00016c, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016d, {[CaseLower] = 0x00016d,[CaseTitle] = 0x00016c,[CaseUpper] = 0x00016c}, NULL},
+ {0x00016e, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x00016f, {[CaseLower] = 0x00016f,[CaseTitle] = 0x00016e,[CaseUpper] = 0x00016e}, NULL},
+ {0x000170, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000171, {[CaseLower] = 0x000171,[CaseTitle] = 0x000170,[CaseUpper] = 0x000170}, NULL},
+ {0x000172, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000173, {[CaseLower] = 0x000173,[CaseTitle] = 0x000172,[CaseUpper] = 0x000172}, NULL},
+ {0x000174, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000175, {[CaseLower] = 0x000175,[CaseTitle] = 0x000174,[CaseUpper] = 0x000174}, NULL},
+ {0x000176, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000177, {[CaseLower] = 0x000177,[CaseTitle] = 0x000176,[CaseUpper] = 0x000176}, NULL},
+ {0x000178, {[CaseLower] = 0x0000ff,[CaseTitle] = 0x000178,[CaseUpper] = 0x000178}, NULL},
+ {0x000179, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017a, {[CaseLower] = 0x00017a,[CaseTitle] = 0x000179,[CaseUpper] = 0x000179}, NULL},
+ {0x00017b, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017c, {[CaseLower] = 0x00017c,[CaseTitle] = 0x00017b,[CaseUpper] = 0x00017b}, NULL},
+ {0x00017d, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017e, {[CaseLower] = 0x00017e,[CaseTitle] = 0x00017d,[CaseUpper] = 0x00017d}, NULL},
+ {0x00017f, {[CaseLower] = 0x00017f,[CaseTitle] = 0x000053,[CaseUpper] = 0x000053}, NULL},
+ {0x000180, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000181, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000182, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000183, {[CaseLower] = 0x000183,[CaseTitle] = 0x000182,[CaseUpper] = 0x000182}, NULL},
+ {0x000184, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000185, {[CaseLower] = 0x000185,[CaseTitle] = 0x000184,[CaseUpper] = 0x000184}, NULL},
+ {0x000186, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000187, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000188, {[CaseLower] = 0x000188,[CaseTitle] = 0x000187,[CaseUpper] = 0x000187}, NULL},
+ {0x000189, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x00018a, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x00018b, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018c, {[CaseLower] = 0x00018c,[CaseTitle] = 0x00018b,[CaseUpper] = 0x00018b}, NULL},
+ {0x00018e, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x00018f, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x000190, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x000191, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000192, {[CaseLower] = 0x000192,[CaseTitle] = 0x000191,[CaseUpper] = 0x000191}, NULL},
+ {0x000193, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000194, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000195, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x000196, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x000197, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000198, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x000199, {[CaseLower] = 0x000199,[CaseTitle] = 0x000198,[CaseUpper] = 0x000198}, NULL},
+ {0x00019a, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00019c, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x00019d, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x00019e, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x00019f, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x0001a0, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a1, {[CaseLower] = 0x0001a1,[CaseTitle] = 0x0001a0,[CaseUpper] = 0x0001a0}, NULL},
+ {0x0001a2, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a3, {[CaseLower] = 0x0001a3,[CaseTitle] = 0x0001a2,[CaseUpper] = 0x0001a2}, NULL},
+ {0x0001a4, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a5, {[CaseLower] = 0x0001a5,[CaseTitle] = 0x0001a4,[CaseUpper] = 0x0001a4}, NULL},
+ {0x0001a6, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x0001a7, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a8, {[CaseLower] = 0x0001a8,[CaseTitle] = 0x0001a7,[CaseUpper] = 0x0001a7}, NULL},
+ {0x0001a9, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x0001ac, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ad, {[CaseLower] = 0x0001ad,[CaseTitle] = 0x0001ac,[CaseUpper] = 0x0001ac}, NULL},
+ {0x0001ae, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x0001af, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b0, {[CaseLower] = 0x0001b0,[CaseTitle] = 0x0001af,[CaseUpper] = 0x0001af}, NULL},
+ {0x0001b1, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x0001b2, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x0001b3, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b4, {[CaseLower] = 0x0001b4,[CaseTitle] = 0x0001b3,[CaseUpper] = 0x0001b3}, NULL},
+ {0x0001b5, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b6, {[CaseLower] = 0x0001b6,[CaseTitle] = 0x0001b5,[CaseUpper] = 0x0001b5}, NULL},
+ {0x0001b7, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x0001b8, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001b9, {[CaseLower] = 0x0001b9,[CaseTitle] = 0x0001b8,[CaseUpper] = 0x0001b8}, NULL},
+ {0x0001bc, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bd, {[CaseLower] = 0x0001bd,[CaseTitle] = 0x0001bc,[CaseUpper] = 0x0001bc}, NULL},
+ {0x0001bf, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001c4, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c5, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c6, {[CaseLower] = 0x0001c6,[CaseTitle] = 0x0001c5,[CaseUpper] = 0x0001c4}, NULL},
+ {0x0001c7, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c8, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001c9, {[CaseLower] = 0x0001c9,[CaseTitle] = 0x0001c8,[CaseUpper] = 0x0001c7}, NULL},
+ {0x0001ca, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cb, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cc, {[CaseLower] = 0x0001cc,[CaseTitle] = 0x0001cb,[CaseUpper] = 0x0001ca}, NULL},
+ {0x0001cd, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001ce, {[CaseLower] = 0x0001ce,[CaseTitle] = 0x0001cd,[CaseUpper] = 0x0001cd}, NULL},
+ {0x0001cf, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d0, {[CaseLower] = 0x0001d0,[CaseTitle] = 0x0001cf,[CaseUpper] = 0x0001cf}, NULL},
+ {0x0001d1, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d2, {[CaseLower] = 0x0001d2,[CaseTitle] = 0x0001d1,[CaseUpper] = 0x0001d1}, NULL},
+ {0x0001d3, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d4, {[CaseLower] = 0x0001d4,[CaseTitle] = 0x0001d3,[CaseUpper] = 0x0001d3}, NULL},
+ {0x0001d5, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d6, {[CaseLower] = 0x0001d6,[CaseTitle] = 0x0001d5,[CaseUpper] = 0x0001d5}, NULL},
+ {0x0001d7, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d8, {[CaseLower] = 0x0001d8,[CaseTitle] = 0x0001d7,[CaseUpper] = 0x0001d7}, NULL},
+ {0x0001d9, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001da, {[CaseLower] = 0x0001da,[CaseTitle] = 0x0001d9,[CaseUpper] = 0x0001d9}, NULL},
+ {0x0001db, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dc, {[CaseLower] = 0x0001dc,[CaseTitle] = 0x0001db,[CaseUpper] = 0x0001db}, NULL},
+ {0x0001dd, {[CaseLower] = 0x0001dd,[CaseTitle] = 0x00018e,[CaseUpper] = 0x00018e}, NULL},
+ {0x0001de, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001df, {[CaseLower] = 0x0001df,[CaseTitle] = 0x0001de,[CaseUpper] = 0x0001de}, NULL},
+ {0x0001e0, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e1, {[CaseLower] = 0x0001e1,[CaseTitle] = 0x0001e0,[CaseUpper] = 0x0001e0}, NULL},
+ {0x0001e2, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e3, {[CaseLower] = 0x0001e3,[CaseTitle] = 0x0001e2,[CaseUpper] = 0x0001e2}, NULL},
+ {0x0001e4, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e5, {[CaseLower] = 0x0001e5,[CaseTitle] = 0x0001e4,[CaseUpper] = 0x0001e4}, NULL},
+ {0x0001e6, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e7, {[CaseLower] = 0x0001e7,[CaseTitle] = 0x0001e6,[CaseUpper] = 0x0001e6}, NULL},
+ {0x0001e8, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001e9, {[CaseLower] = 0x0001e9,[CaseTitle] = 0x0001e8,[CaseUpper] = 0x0001e8}, NULL},
+ {0x0001ea, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001eb, {[CaseLower] = 0x0001eb,[CaseTitle] = 0x0001ea,[CaseUpper] = 0x0001ea}, NULL},
+ {0x0001ec, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ed, {[CaseLower] = 0x0001ed,[CaseTitle] = 0x0001ec,[CaseUpper] = 0x0001ec}, NULL},
+ {0x0001ee, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001ef, {[CaseLower] = 0x0001ef,[CaseTitle] = 0x0001ee,[CaseUpper] = 0x0001ee}, NULL},
+ {0x0001f0, {[CaseLower] = 0x0001f0,[CaseTitle] = 0x0001f0,[CaseUpper] = 0x0001f0}, &special_case[3]},
+ {0x0001f1, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f2, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f3, {[CaseLower] = 0x0001f3,[CaseTitle] = 0x0001f2,[CaseUpper] = 0x0001f1}, NULL},
+ {0x0001f4, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f5, {[CaseLower] = 0x0001f5,[CaseTitle] = 0x0001f4,[CaseUpper] = 0x0001f4}, NULL},
+ {0x0001f6, {[CaseLower] = 0x000195,[CaseTitle] = 0x0001f6,[CaseUpper] = 0x0001f6}, NULL},
+ {0x0001f7, {[CaseLower] = 0x0001bf,[CaseTitle] = 0x0001f7,[CaseUpper] = 0x0001f7}, NULL},
+ {0x0001f8, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001f9, {[CaseLower] = 0x0001f9,[CaseTitle] = 0x0001f8,[CaseUpper] = 0x0001f8}, NULL},
+ {0x0001fa, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fb, {[CaseLower] = 0x0001fb,[CaseTitle] = 0x0001fa,[CaseUpper] = 0x0001fa}, NULL},
+ {0x0001fc, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fd, {[CaseLower] = 0x0001fd,[CaseTitle] = 0x0001fc,[CaseUpper] = 0x0001fc}, NULL},
+ {0x0001fe, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x0001ff, {[CaseLower] = 0x0001ff,[CaseTitle] = 0x0001fe,[CaseUpper] = 0x0001fe}, NULL},
+ {0x000200, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000201, {[CaseLower] = 0x000201,[CaseTitle] = 0x000200,[CaseUpper] = 0x000200}, NULL},
+ {0x000202, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000203, {[CaseLower] = 0x000203,[CaseTitle] = 0x000202,[CaseUpper] = 0x000202}, NULL},
+ {0x000204, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000205, {[CaseLower] = 0x000205,[CaseTitle] = 0x000204,[CaseUpper] = 0x000204}, NULL},
+ {0x000206, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000207, {[CaseLower] = 0x000207,[CaseTitle] = 0x000206,[CaseUpper] = 0x000206}, NULL},
+ {0x000208, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x000209, {[CaseLower] = 0x000209,[CaseTitle] = 0x000208,[CaseUpper] = 0x000208}, NULL},
+ {0x00020a, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020b, {[CaseLower] = 0x00020b,[CaseTitle] = 0x00020a,[CaseUpper] = 0x00020a}, NULL},
+ {0x00020c, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020d, {[CaseLower] = 0x00020d,[CaseTitle] = 0x00020c,[CaseUpper] = 0x00020c}, NULL},
+ {0x00020e, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x00020f, {[CaseLower] = 0x00020f,[CaseTitle] = 0x00020e,[CaseUpper] = 0x00020e}, NULL},
+ {0x000210, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000211, {[CaseLower] = 0x000211,[CaseTitle] = 0x000210,[CaseUpper] = 0x000210}, NULL},
+ {0x000212, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000213, {[CaseLower] = 0x000213,[CaseTitle] = 0x000212,[CaseUpper] = 0x000212}, NULL},
+ {0x000214, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000215, {[CaseLower] = 0x000215,[CaseTitle] = 0x000214,[CaseUpper] = 0x000214}, NULL},
+ {0x000216, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000217, {[CaseLower] = 0x000217,[CaseTitle] = 0x000216,[CaseUpper] = 0x000216}, NULL},
+ {0x000218, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x000219, {[CaseLower] = 0x000219,[CaseTitle] = 0x000218,[CaseUpper] = 0x000218}, NULL},
+ {0x00021a, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021b, {[CaseLower] = 0x00021b,[CaseTitle] = 0x00021a,[CaseUpper] = 0x00021a}, NULL},
+ {0x00021c, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021d, {[CaseLower] = 0x00021d,[CaseTitle] = 0x00021c,[CaseUpper] = 0x00021c}, NULL},
+ {0x00021e, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x00021f, {[CaseLower] = 0x00021f,[CaseTitle] = 0x00021e,[CaseUpper] = 0x00021e}, NULL},
+ {0x000220, {[CaseLower] = 0x00019e,[CaseTitle] = 0x000220,[CaseUpper] = 0x000220}, NULL},
+ {0x000222, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000223, {[CaseLower] = 0x000223,[CaseTitle] = 0x000222,[CaseUpper] = 0x000222}, NULL},
+ {0x000224, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000225, {[CaseLower] = 0x000225,[CaseTitle] = 0x000224,[CaseUpper] = 0x000224}, NULL},
+ {0x000226, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000227, {[CaseLower] = 0x000227,[CaseTitle] = 0x000226,[CaseUpper] = 0x000226}, NULL},
+ {0x000228, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x000229, {[CaseLower] = 0x000229,[CaseTitle] = 0x000228,[CaseUpper] = 0x000228}, NULL},
+ {0x00022a, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022b, {[CaseLower] = 0x00022b,[CaseTitle] = 0x00022a,[CaseUpper] = 0x00022a}, NULL},
+ {0x00022c, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022d, {[CaseLower] = 0x00022d,[CaseTitle] = 0x00022c,[CaseUpper] = 0x00022c}, NULL},
+ {0x00022e, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x00022f, {[CaseLower] = 0x00022f,[CaseTitle] = 0x00022e,[CaseUpper] = 0x00022e}, NULL},
+ {0x000230, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000231, {[CaseLower] = 0x000231,[CaseTitle] = 0x000230,[CaseUpper] = 0x000230}, NULL},
+ {0x000232, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x000233, {[CaseLower] = 0x000233,[CaseTitle] = 0x000232,[CaseUpper] = 0x000232}, NULL},
+ {0x00023a, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x00023b, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023c, {[CaseLower] = 0x00023c,[CaseTitle] = 0x00023b,[CaseUpper] = 0x00023b}, NULL},
+ {0x00023d, {[CaseLower] = 0x00019a,[CaseTitle] = 0x00023d,[CaseUpper] = 0x00023d}, NULL},
+ {0x00023e, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x00023f, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x000240, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x000241, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000242, {[CaseLower] = 0x000242,[CaseTitle] = 0x000241,[CaseUpper] = 0x000241}, NULL},
+ {0x000243, {[CaseLower] = 0x000180,[CaseTitle] = 0x000243,[CaseUpper] = 0x000243}, NULL},
+ {0x000244, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x000245, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000246, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000247, {[CaseLower] = 0x000247,[CaseTitle] = 0x000246,[CaseUpper] = 0x000246}, NULL},
+ {0x000248, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x000249, {[CaseLower] = 0x000249,[CaseTitle] = 0x000248,[CaseUpper] = 0x000248}, NULL},
+ {0x00024a, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024b, {[CaseLower] = 0x00024b,[CaseTitle] = 0x00024a,[CaseUpper] = 0x00024a}, NULL},
+ {0x00024c, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024d, {[CaseLower] = 0x00024d,[CaseTitle] = 0x00024c,[CaseUpper] = 0x00024c}, NULL},
+ {0x00024e, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x00024f, {[CaseLower] = 0x00024f,[CaseTitle] = 0x00024e,[CaseUpper] = 0x00024e}, NULL},
+ {0x000250, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x000251, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x000252, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x000253, {[CaseLower] = 0x000253,[CaseTitle] = 0x000181,[CaseUpper] = 0x000181}, NULL},
+ {0x000254, {[CaseLower] = 0x000254,[CaseTitle] = 0x000186,[CaseUpper] = 0x000186}, NULL},
+ {0x000256, {[CaseLower] = 0x000256,[CaseTitle] = 0x000189,[CaseUpper] = 0x000189}, NULL},
+ {0x000257, {[CaseLower] = 0x000257,[CaseTitle] = 0x00018a,[CaseUpper] = 0x00018a}, NULL},
+ {0x000259, {[CaseLower] = 0x000259,[CaseTitle] = 0x00018f,[CaseUpper] = 0x00018f}, NULL},
+ {0x00025b, {[CaseLower] = 0x00025b,[CaseTitle] = 0x000190,[CaseUpper] = 0x000190}, NULL},
+ {0x00025c, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x000260, {[CaseLower] = 0x000260,[CaseTitle] = 0x000193,[CaseUpper] = 0x000193}, NULL},
+ {0x000261, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x000263, {[CaseLower] = 0x000263,[CaseTitle] = 0x000194,[CaseUpper] = 0x000194}, NULL},
+ {0x000265, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x000266, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x000268, {[CaseLower] = 0x000268,[CaseTitle] = 0x000197,[CaseUpper] = 0x000197}, NULL},
+ {0x000269, {[CaseLower] = 0x000269,[CaseTitle] = 0x000196,[CaseUpper] = 0x000196}, NULL},
+ {0x00026a, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00026b, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x00026c, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00026f, {[CaseLower] = 0x00026f,[CaseTitle] = 0x00019c,[CaseUpper] = 0x00019c}, NULL},
+ {0x000271, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x000272, {[CaseLower] = 0x000272,[CaseTitle] = 0x00019d,[CaseUpper] = 0x00019d}, NULL},
+ {0x000275, {[CaseLower] = 0x000275,[CaseTitle] = 0x00019f,[CaseUpper] = 0x00019f}, NULL},
+ {0x00027d, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x000280, {[CaseLower] = 0x000280,[CaseTitle] = 0x0001a6,[CaseUpper] = 0x0001a6}, NULL},
+ {0x000282, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x000283, {[CaseLower] = 0x000283,[CaseTitle] = 0x0001a9,[CaseUpper] = 0x0001a9}, NULL},
+ {0x000287, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x000288, {[CaseLower] = 0x000288,[CaseTitle] = 0x0001ae,[CaseUpper] = 0x0001ae}, NULL},
+ {0x000289, {[CaseLower] = 0x000289,[CaseTitle] = 0x000244,[CaseUpper] = 0x000244}, NULL},
+ {0x00028a, {[CaseLower] = 0x00028a,[CaseTitle] = 0x0001b1,[CaseUpper] = 0x0001b1}, NULL},
+ {0x00028b, {[CaseLower] = 0x00028b,[CaseTitle] = 0x0001b2,[CaseUpper] = 0x0001b2}, NULL},
+ {0x00028c, {[CaseLower] = 0x00028c,[CaseTitle] = 0x000245,[CaseUpper] = 0x000245}, NULL},
+ {0x000292, {[CaseLower] = 0x000292,[CaseTitle] = 0x0001b7,[CaseUpper] = 0x0001b7}, NULL},
+ {0x00029d, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00029e, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x000345, {[CaseLower] = 0x000345,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x000370, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000371, {[CaseLower] = 0x000371,[CaseTitle] = 0x000370,[CaseUpper] = 0x000370}, NULL},
+ {0x000372, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000373, {[CaseLower] = 0x000373,[CaseTitle] = 0x000372,[CaseUpper] = 0x000372}, NULL},
+ {0x000376, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x000377, {[CaseLower] = 0x000377,[CaseTitle] = 0x000376,[CaseUpper] = 0x000376}, NULL},
+ {0x00037b, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x00037c, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x00037d, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x00037f, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x000386, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x000388, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x000389, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x00038a, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x00038c, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x00038e, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x00038f, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x000390, {[CaseLower] = 0x000390,[CaseTitle] = 0x000390,[CaseUpper] = 0x000390}, &special_case[4]},
+ {0x000391, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x000392, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x000393, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x000394, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x000395, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x000396, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x000397, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x000398, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x000399, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x00039a, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x00039b, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x00039c, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x00039d, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x00039e, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x00039f, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003a0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003a1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003a3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, &special_case[5]},
+ {0x0003a4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003a5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003a6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003a7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003a8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003a9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003aa, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003ab, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003ac, {[CaseLower] = 0x0003ac,[CaseTitle] = 0x000386,[CaseUpper] = 0x000386}, NULL},
+ {0x0003ad, {[CaseLower] = 0x0003ad,[CaseTitle] = 0x000388,[CaseUpper] = 0x000388}, NULL},
+ {0x0003ae, {[CaseLower] = 0x0003ae,[CaseTitle] = 0x000389,[CaseUpper] = 0x000389}, NULL},
+ {0x0003af, {[CaseLower] = 0x0003af,[CaseTitle] = 0x00038a,[CaseUpper] = 0x00038a}, NULL},
+ {0x0003b0, {[CaseLower] = 0x0003b0,[CaseTitle] = 0x0003b0,[CaseUpper] = 0x0003b0}, &special_case[6]},
+ {0x0003b1, {[CaseLower] = 0x0003b1,[CaseTitle] = 0x000391,[CaseUpper] = 0x000391}, NULL},
+ {0x0003b2, {[CaseLower] = 0x0003b2,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003b3, {[CaseLower] = 0x0003b3,[CaseTitle] = 0x000393,[CaseUpper] = 0x000393}, NULL},
+ {0x0003b4, {[CaseLower] = 0x0003b4,[CaseTitle] = 0x000394,[CaseUpper] = 0x000394}, NULL},
+ {0x0003b5, {[CaseLower] = 0x0003b5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003b6, {[CaseLower] = 0x0003b6,[CaseTitle] = 0x000396,[CaseUpper] = 0x000396}, NULL},
+ {0x0003b7, {[CaseLower] = 0x0003b7,[CaseTitle] = 0x000397,[CaseUpper] = 0x000397}, NULL},
+ {0x0003b8, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003b9, {[CaseLower] = 0x0003b9,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x0003ba, {[CaseLower] = 0x0003ba,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003bb, {[CaseLower] = 0x0003bb,[CaseTitle] = 0x00039b,[CaseUpper] = 0x00039b}, NULL},
+ {0x0003bc, {[CaseLower] = 0x0003bc,[CaseTitle] = 0x00039c,[CaseUpper] = 0x00039c}, NULL},
+ {0x0003bd, {[CaseLower] = 0x0003bd,[CaseTitle] = 0x00039d,[CaseUpper] = 0x00039d}, NULL},
+ {0x0003be, {[CaseLower] = 0x0003be,[CaseTitle] = 0x00039e,[CaseUpper] = 0x00039e}, NULL},
+ {0x0003bf, {[CaseLower] = 0x0003bf,[CaseTitle] = 0x00039f,[CaseUpper] = 0x00039f}, NULL},
+ {0x0003c0, {[CaseLower] = 0x0003c0,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003c1, {[CaseLower] = 0x0003c1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003c2, {[CaseLower] = 0x0003c2,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c3, {[CaseLower] = 0x0003c3,[CaseTitle] = 0x0003a3,[CaseUpper] = 0x0003a3}, NULL},
+ {0x0003c4, {[CaseLower] = 0x0003c4,[CaseTitle] = 0x0003a4,[CaseUpper] = 0x0003a4}, NULL},
+ {0x0003c5, {[CaseLower] = 0x0003c5,[CaseTitle] = 0x0003a5,[CaseUpper] = 0x0003a5}, NULL},
+ {0x0003c6, {[CaseLower] = 0x0003c6,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003c7, {[CaseLower] = 0x0003c7,[CaseTitle] = 0x0003a7,[CaseUpper] = 0x0003a7}, NULL},
+ {0x0003c8, {[CaseLower] = 0x0003c8,[CaseTitle] = 0x0003a8,[CaseUpper] = 0x0003a8}, NULL},
+ {0x0003c9, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x0003a9,[CaseUpper] = 0x0003a9}, NULL},
+ {0x0003ca, {[CaseLower] = 0x0003ca,[CaseTitle] = 0x0003aa,[CaseUpper] = 0x0003aa}, NULL},
+ {0x0003cb, {[CaseLower] = 0x0003cb,[CaseTitle] = 0x0003ab,[CaseUpper] = 0x0003ab}, NULL},
+ {0x0003cc, {[CaseLower] = 0x0003cc,[CaseTitle] = 0x00038c,[CaseUpper] = 0x00038c}, NULL},
+ {0x0003cd, {[CaseLower] = 0x0003cd,[CaseTitle] = 0x00038e,[CaseUpper] = 0x00038e}, NULL},
+ {0x0003ce, {[CaseLower] = 0x0003ce,[CaseTitle] = 0x00038f,[CaseUpper] = 0x00038f}, NULL},
+ {0x0003cf, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d0, {[CaseLower] = 0x0003d0,[CaseTitle] = 0x000392,[CaseUpper] = 0x000392}, NULL},
+ {0x0003d1, {[CaseLower] = 0x0003d1,[CaseTitle] = 0x000398,[CaseUpper] = 0x000398}, NULL},
+ {0x0003d5, {[CaseLower] = 0x0003d5,[CaseTitle] = 0x0003a6,[CaseUpper] = 0x0003a6}, NULL},
+ {0x0003d6, {[CaseLower] = 0x0003d6,[CaseTitle] = 0x0003a0,[CaseUpper] = 0x0003a0}, NULL},
+ {0x0003d7, {[CaseLower] = 0x0003d7,[CaseTitle] = 0x0003cf,[CaseUpper] = 0x0003cf}, NULL},
+ {0x0003d8, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003d9, {[CaseLower] = 0x0003d9,[CaseTitle] = 0x0003d8,[CaseUpper] = 0x0003d8}, NULL},
+ {0x0003da, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003db, {[CaseLower] = 0x0003db,[CaseTitle] = 0x0003da,[CaseUpper] = 0x0003da}, NULL},
+ {0x0003dc, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003dd, {[CaseLower] = 0x0003dd,[CaseTitle] = 0x0003dc,[CaseUpper] = 0x0003dc}, NULL},
+ {0x0003de, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003df, {[CaseLower] = 0x0003df,[CaseTitle] = 0x0003de,[CaseUpper] = 0x0003de}, NULL},
+ {0x0003e0, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e1, {[CaseLower] = 0x0003e1,[CaseTitle] = 0x0003e0,[CaseUpper] = 0x0003e0}, NULL},
+ {0x0003e2, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e3, {[CaseLower] = 0x0003e3,[CaseTitle] = 0x0003e2,[CaseUpper] = 0x0003e2}, NULL},
+ {0x0003e4, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e5, {[CaseLower] = 0x0003e5,[CaseTitle] = 0x0003e4,[CaseUpper] = 0x0003e4}, NULL},
+ {0x0003e6, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e7, {[CaseLower] = 0x0003e7,[CaseTitle] = 0x0003e6,[CaseUpper] = 0x0003e6}, NULL},
+ {0x0003e8, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003e9, {[CaseLower] = 0x0003e9,[CaseTitle] = 0x0003e8,[CaseUpper] = 0x0003e8}, NULL},
+ {0x0003ea, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003eb, {[CaseLower] = 0x0003eb,[CaseTitle] = 0x0003ea,[CaseUpper] = 0x0003ea}, NULL},
+ {0x0003ec, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ed, {[CaseLower] = 0x0003ed,[CaseTitle] = 0x0003ec,[CaseUpper] = 0x0003ec}, NULL},
+ {0x0003ee, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003ef, {[CaseLower] = 0x0003ef,[CaseTitle] = 0x0003ee,[CaseUpper] = 0x0003ee}, NULL},
+ {0x0003f0, {[CaseLower] = 0x0003f0,[CaseTitle] = 0x00039a,[CaseUpper] = 0x00039a}, NULL},
+ {0x0003f1, {[CaseLower] = 0x0003f1,[CaseTitle] = 0x0003a1,[CaseUpper] = 0x0003a1}, NULL},
+ {0x0003f2, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003f3, {[CaseLower] = 0x0003f3,[CaseTitle] = 0x00037f,[CaseUpper] = 0x00037f}, NULL},
+ {0x0003f4, {[CaseLower] = 0x0003b8,[CaseTitle] = 0x0003f4,[CaseUpper] = 0x0003f4}, NULL},
+ {0x0003f5, {[CaseLower] = 0x0003f5,[CaseTitle] = 0x000395,[CaseUpper] = 0x000395}, NULL},
+ {0x0003f7, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f8, {[CaseLower] = 0x0003f8,[CaseTitle] = 0x0003f7,[CaseUpper] = 0x0003f7}, NULL},
+ {0x0003f9, {[CaseLower] = 0x0003f2,[CaseTitle] = 0x0003f9,[CaseUpper] = 0x0003f9}, NULL},
+ {0x0003fa, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fb, {[CaseLower] = 0x0003fb,[CaseTitle] = 0x0003fa,[CaseUpper] = 0x0003fa}, NULL},
+ {0x0003fd, {[CaseLower] = 0x00037b,[CaseTitle] = 0x0003fd,[CaseUpper] = 0x0003fd}, NULL},
+ {0x0003fe, {[CaseLower] = 0x00037c,[CaseTitle] = 0x0003fe,[CaseUpper] = 0x0003fe}, NULL},
+ {0x0003ff, {[CaseLower] = 0x00037d,[CaseTitle] = 0x0003ff,[CaseUpper] = 0x0003ff}, NULL},
+ {0x000400, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000401, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000402, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000403, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000404, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000405, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000406, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000407, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000408, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000409, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00040a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00040b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00040c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00040d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00040e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00040f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000410, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000411, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000412, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000413, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000414, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000415, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000416, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000417, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000418, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000419, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00041a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00041b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00041c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00041d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00041e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00041f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000420, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000421, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000422, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000423, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000424, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000425, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000426, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000427, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000428, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000429, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00042a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00042b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00042c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00042d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00042e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00042f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000430, {[CaseLower] = 0x000430,[CaseTitle] = 0x000410,[CaseUpper] = 0x000410}, NULL},
+ {0x000431, {[CaseLower] = 0x000431,[CaseTitle] = 0x000411,[CaseUpper] = 0x000411}, NULL},
+ {0x000432, {[CaseLower] = 0x000432,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x000433, {[CaseLower] = 0x000433,[CaseTitle] = 0x000413,[CaseUpper] = 0x000413}, NULL},
+ {0x000434, {[CaseLower] = 0x000434,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x000435, {[CaseLower] = 0x000435,[CaseTitle] = 0x000415,[CaseUpper] = 0x000415}, NULL},
+ {0x000436, {[CaseLower] = 0x000436,[CaseTitle] = 0x000416,[CaseUpper] = 0x000416}, NULL},
+ {0x000437, {[CaseLower] = 0x000437,[CaseTitle] = 0x000417,[CaseUpper] = 0x000417}, NULL},
+ {0x000438, {[CaseLower] = 0x000438,[CaseTitle] = 0x000418,[CaseUpper] = 0x000418}, NULL},
+ {0x000439, {[CaseLower] = 0x000439,[CaseTitle] = 0x000419,[CaseUpper] = 0x000419}, NULL},
+ {0x00043a, {[CaseLower] = 0x00043a,[CaseTitle] = 0x00041a,[CaseUpper] = 0x00041a}, NULL},
+ {0x00043b, {[CaseLower] = 0x00043b,[CaseTitle] = 0x00041b,[CaseUpper] = 0x00041b}, NULL},
+ {0x00043c, {[CaseLower] = 0x00043c,[CaseTitle] = 0x00041c,[CaseUpper] = 0x00041c}, NULL},
+ {0x00043d, {[CaseLower] = 0x00043d,[CaseTitle] = 0x00041d,[CaseUpper] = 0x00041d}, NULL},
+ {0x00043e, {[CaseLower] = 0x00043e,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x00043f, {[CaseLower] = 0x00043f,[CaseTitle] = 0x00041f,[CaseUpper] = 0x00041f}, NULL},
+ {0x000440, {[CaseLower] = 0x000440,[CaseTitle] = 0x000420,[CaseUpper] = 0x000420}, NULL},
+ {0x000441, {[CaseLower] = 0x000441,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x000442, {[CaseLower] = 0x000442,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x000443, {[CaseLower] = 0x000443,[CaseTitle] = 0x000423,[CaseUpper] = 0x000423}, NULL},
+ {0x000444, {[CaseLower] = 0x000444,[CaseTitle] = 0x000424,[CaseUpper] = 0x000424}, NULL},
+ {0x000445, {[CaseLower] = 0x000445,[CaseTitle] = 0x000425,[CaseUpper] = 0x000425}, NULL},
+ {0x000446, {[CaseLower] = 0x000446,[CaseTitle] = 0x000426,[CaseUpper] = 0x000426}, NULL},
+ {0x000447, {[CaseLower] = 0x000447,[CaseTitle] = 0x000427,[CaseUpper] = 0x000427}, NULL},
+ {0x000448, {[CaseLower] = 0x000448,[CaseTitle] = 0x000428,[CaseUpper] = 0x000428}, NULL},
+ {0x000449, {[CaseLower] = 0x000449,[CaseTitle] = 0x000429,[CaseUpper] = 0x000429}, NULL},
+ {0x00044a, {[CaseLower] = 0x00044a,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x00044b, {[CaseLower] = 0x00044b,[CaseTitle] = 0x00042b,[CaseUpper] = 0x00042b}, NULL},
+ {0x00044c, {[CaseLower] = 0x00044c,[CaseTitle] = 0x00042c,[CaseUpper] = 0x00042c}, NULL},
+ {0x00044d, {[CaseLower] = 0x00044d,[CaseTitle] = 0x00042d,[CaseUpper] = 0x00042d}, NULL},
+ {0x00044e, {[CaseLower] = 0x00044e,[CaseTitle] = 0x00042e,[CaseUpper] = 0x00042e}, NULL},
+ {0x00044f, {[CaseLower] = 0x00044f,[CaseTitle] = 0x00042f,[CaseUpper] = 0x00042f}, NULL},
+ {0x000450, {[CaseLower] = 0x000450,[CaseTitle] = 0x000400,[CaseUpper] = 0x000400}, NULL},
+ {0x000451, {[CaseLower] = 0x000451,[CaseTitle] = 0x000401,[CaseUpper] = 0x000401}, NULL},
+ {0x000452, {[CaseLower] = 0x000452,[CaseTitle] = 0x000402,[CaseUpper] = 0x000402}, NULL},
+ {0x000453, {[CaseLower] = 0x000453,[CaseTitle] = 0x000403,[CaseUpper] = 0x000403}, NULL},
+ {0x000454, {[CaseLower] = 0x000454,[CaseTitle] = 0x000404,[CaseUpper] = 0x000404}, NULL},
+ {0x000455, {[CaseLower] = 0x000455,[CaseTitle] = 0x000405,[CaseUpper] = 0x000405}, NULL},
+ {0x000456, {[CaseLower] = 0x000456,[CaseTitle] = 0x000406,[CaseUpper] = 0x000406}, NULL},
+ {0x000457, {[CaseLower] = 0x000457,[CaseTitle] = 0x000407,[CaseUpper] = 0x000407}, NULL},
+ {0x000458, {[CaseLower] = 0x000458,[CaseTitle] = 0x000408,[CaseUpper] = 0x000408}, NULL},
+ {0x000459, {[CaseLower] = 0x000459,[CaseTitle] = 0x000409,[CaseUpper] = 0x000409}, NULL},
+ {0x00045a, {[CaseLower] = 0x00045a,[CaseTitle] = 0x00040a,[CaseUpper] = 0x00040a}, NULL},
+ {0x00045b, {[CaseLower] = 0x00045b,[CaseTitle] = 0x00040b,[CaseUpper] = 0x00040b}, NULL},
+ {0x00045c, {[CaseLower] = 0x00045c,[CaseTitle] = 0x00040c,[CaseUpper] = 0x00040c}, NULL},
+ {0x00045d, {[CaseLower] = 0x00045d,[CaseTitle] = 0x00040d,[CaseUpper] = 0x00040d}, NULL},
+ {0x00045e, {[CaseLower] = 0x00045e,[CaseTitle] = 0x00040e,[CaseUpper] = 0x00040e}, NULL},
+ {0x00045f, {[CaseLower] = 0x00045f,[CaseTitle] = 0x00040f,[CaseUpper] = 0x00040f}, NULL},
+ {0x000460, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000461, {[CaseLower] = 0x000461,[CaseTitle] = 0x000460,[CaseUpper] = 0x000460}, NULL},
+ {0x000462, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000463, {[CaseLower] = 0x000463,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x000464, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000465, {[CaseLower] = 0x000465,[CaseTitle] = 0x000464,[CaseUpper] = 0x000464}, NULL},
+ {0x000466, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000467, {[CaseLower] = 0x000467,[CaseTitle] = 0x000466,[CaseUpper] = 0x000466}, NULL},
+ {0x000468, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x000469, {[CaseLower] = 0x000469,[CaseTitle] = 0x000468,[CaseUpper] = 0x000468}, NULL},
+ {0x00046a, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046b, {[CaseLower] = 0x00046b,[CaseTitle] = 0x00046a,[CaseUpper] = 0x00046a}, NULL},
+ {0x00046c, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046d, {[CaseLower] = 0x00046d,[CaseTitle] = 0x00046c,[CaseUpper] = 0x00046c}, NULL},
+ {0x00046e, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x00046f, {[CaseLower] = 0x00046f,[CaseTitle] = 0x00046e,[CaseUpper] = 0x00046e}, NULL},
+ {0x000470, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000471, {[CaseLower] = 0x000471,[CaseTitle] = 0x000470,[CaseUpper] = 0x000470}, NULL},
+ {0x000472, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000473, {[CaseLower] = 0x000473,[CaseTitle] = 0x000472,[CaseUpper] = 0x000472}, NULL},
+ {0x000474, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000475, {[CaseLower] = 0x000475,[CaseTitle] = 0x000474,[CaseUpper] = 0x000474}, NULL},
+ {0x000476, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000477, {[CaseLower] = 0x000477,[CaseTitle] = 0x000476,[CaseUpper] = 0x000476}, NULL},
+ {0x000478, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x000479, {[CaseLower] = 0x000479,[CaseTitle] = 0x000478,[CaseUpper] = 0x000478}, NULL},
+ {0x00047a, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047b, {[CaseLower] = 0x00047b,[CaseTitle] = 0x00047a,[CaseUpper] = 0x00047a}, NULL},
+ {0x00047c, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047d, {[CaseLower] = 0x00047d,[CaseTitle] = 0x00047c,[CaseUpper] = 0x00047c}, NULL},
+ {0x00047e, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x00047f, {[CaseLower] = 0x00047f,[CaseTitle] = 0x00047e,[CaseUpper] = 0x00047e}, NULL},
+ {0x000480, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x000481, {[CaseLower] = 0x000481,[CaseTitle] = 0x000480,[CaseUpper] = 0x000480}, NULL},
+ {0x00048a, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048b, {[CaseLower] = 0x00048b,[CaseTitle] = 0x00048a,[CaseUpper] = 0x00048a}, NULL},
+ {0x00048c, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048d, {[CaseLower] = 0x00048d,[CaseTitle] = 0x00048c,[CaseUpper] = 0x00048c}, NULL},
+ {0x00048e, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x00048f, {[CaseLower] = 0x00048f,[CaseTitle] = 0x00048e,[CaseUpper] = 0x00048e}, NULL},
+ {0x000490, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000491, {[CaseLower] = 0x000491,[CaseTitle] = 0x000490,[CaseUpper] = 0x000490}, NULL},
+ {0x000492, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000493, {[CaseLower] = 0x000493,[CaseTitle] = 0x000492,[CaseUpper] = 0x000492}, NULL},
+ {0x000494, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000495, {[CaseLower] = 0x000495,[CaseTitle] = 0x000494,[CaseUpper] = 0x000494}, NULL},
+ {0x000496, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000497, {[CaseLower] = 0x000497,[CaseTitle] = 0x000496,[CaseUpper] = 0x000496}, NULL},
+ {0x000498, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x000499, {[CaseLower] = 0x000499,[CaseTitle] = 0x000498,[CaseUpper] = 0x000498}, NULL},
+ {0x00049a, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049b, {[CaseLower] = 0x00049b,[CaseTitle] = 0x00049a,[CaseUpper] = 0x00049a}, NULL},
+ {0x00049c, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049d, {[CaseLower] = 0x00049d,[CaseTitle] = 0x00049c,[CaseUpper] = 0x00049c}, NULL},
+ {0x00049e, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x00049f, {[CaseLower] = 0x00049f,[CaseTitle] = 0x00049e,[CaseUpper] = 0x00049e}, NULL},
+ {0x0004a0, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a1, {[CaseLower] = 0x0004a1,[CaseTitle] = 0x0004a0,[CaseUpper] = 0x0004a0}, NULL},
+ {0x0004a2, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a3, {[CaseLower] = 0x0004a3,[CaseTitle] = 0x0004a2,[CaseUpper] = 0x0004a2}, NULL},
+ {0x0004a4, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a5, {[CaseLower] = 0x0004a5,[CaseTitle] = 0x0004a4,[CaseUpper] = 0x0004a4}, NULL},
+ {0x0004a6, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a7, {[CaseLower] = 0x0004a7,[CaseTitle] = 0x0004a6,[CaseUpper] = 0x0004a6}, NULL},
+ {0x0004a8, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004a9, {[CaseLower] = 0x0004a9,[CaseTitle] = 0x0004a8,[CaseUpper] = 0x0004a8}, NULL},
+ {0x0004aa, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ab, {[CaseLower] = 0x0004ab,[CaseTitle] = 0x0004aa,[CaseUpper] = 0x0004aa}, NULL},
+ {0x0004ac, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ad, {[CaseLower] = 0x0004ad,[CaseTitle] = 0x0004ac,[CaseUpper] = 0x0004ac}, NULL},
+ {0x0004ae, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004af, {[CaseLower] = 0x0004af,[CaseTitle] = 0x0004ae,[CaseUpper] = 0x0004ae}, NULL},
+ {0x0004b0, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b1, {[CaseLower] = 0x0004b1,[CaseTitle] = 0x0004b0,[CaseUpper] = 0x0004b0}, NULL},
+ {0x0004b2, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b3, {[CaseLower] = 0x0004b3,[CaseTitle] = 0x0004b2,[CaseUpper] = 0x0004b2}, NULL},
+ {0x0004b4, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b5, {[CaseLower] = 0x0004b5,[CaseTitle] = 0x0004b4,[CaseUpper] = 0x0004b4}, NULL},
+ {0x0004b6, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b7, {[CaseLower] = 0x0004b7,[CaseTitle] = 0x0004b6,[CaseUpper] = 0x0004b6}, NULL},
+ {0x0004b8, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004b9, {[CaseLower] = 0x0004b9,[CaseTitle] = 0x0004b8,[CaseUpper] = 0x0004b8}, NULL},
+ {0x0004ba, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bb, {[CaseLower] = 0x0004bb,[CaseTitle] = 0x0004ba,[CaseUpper] = 0x0004ba}, NULL},
+ {0x0004bc, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004bd, {[CaseLower] = 0x0004bd,[CaseTitle] = 0x0004bc,[CaseUpper] = 0x0004bc}, NULL},
+ {0x0004be, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004bf, {[CaseLower] = 0x0004bf,[CaseTitle] = 0x0004be,[CaseUpper] = 0x0004be}, NULL},
+ {0x0004c0, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004c1, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c2, {[CaseLower] = 0x0004c2,[CaseTitle] = 0x0004c1,[CaseUpper] = 0x0004c1}, NULL},
+ {0x0004c3, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c4, {[CaseLower] = 0x0004c4,[CaseTitle] = 0x0004c3,[CaseUpper] = 0x0004c3}, NULL},
+ {0x0004c5, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c6, {[CaseLower] = 0x0004c6,[CaseTitle] = 0x0004c5,[CaseUpper] = 0x0004c5}, NULL},
+ {0x0004c7, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c8, {[CaseLower] = 0x0004c8,[CaseTitle] = 0x0004c7,[CaseUpper] = 0x0004c7}, NULL},
+ {0x0004c9, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004ca, {[CaseLower] = 0x0004ca,[CaseTitle] = 0x0004c9,[CaseUpper] = 0x0004c9}, NULL},
+ {0x0004cb, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cc, {[CaseLower] = 0x0004cc,[CaseTitle] = 0x0004cb,[CaseUpper] = 0x0004cb}, NULL},
+ {0x0004cd, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004ce, {[CaseLower] = 0x0004ce,[CaseTitle] = 0x0004cd,[CaseUpper] = 0x0004cd}, NULL},
+ {0x0004cf, {[CaseLower] = 0x0004cf,[CaseTitle] = 0x0004c0,[CaseUpper] = 0x0004c0}, NULL},
+ {0x0004d0, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d1, {[CaseLower] = 0x0004d1,[CaseTitle] = 0x0004d0,[CaseUpper] = 0x0004d0}, NULL},
+ {0x0004d2, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d3, {[CaseLower] = 0x0004d3,[CaseTitle] = 0x0004d2,[CaseUpper] = 0x0004d2}, NULL},
+ {0x0004d4, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d5, {[CaseLower] = 0x0004d5,[CaseTitle] = 0x0004d4,[CaseUpper] = 0x0004d4}, NULL},
+ {0x0004d6, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d7, {[CaseLower] = 0x0004d7,[CaseTitle] = 0x0004d6,[CaseUpper] = 0x0004d6}, NULL},
+ {0x0004d8, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004d9, {[CaseLower] = 0x0004d9,[CaseTitle] = 0x0004d8,[CaseUpper] = 0x0004d8}, NULL},
+ {0x0004da, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004db, {[CaseLower] = 0x0004db,[CaseTitle] = 0x0004da,[CaseUpper] = 0x0004da}, NULL},
+ {0x0004dc, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004dd, {[CaseLower] = 0x0004dd,[CaseTitle] = 0x0004dc,[CaseUpper] = 0x0004dc}, NULL},
+ {0x0004de, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004df, {[CaseLower] = 0x0004df,[CaseTitle] = 0x0004de,[CaseUpper] = 0x0004de}, NULL},
+ {0x0004e0, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e1, {[CaseLower] = 0x0004e1,[CaseTitle] = 0x0004e0,[CaseUpper] = 0x0004e0}, NULL},
+ {0x0004e2, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e3, {[CaseLower] = 0x0004e3,[CaseTitle] = 0x0004e2,[CaseUpper] = 0x0004e2}, NULL},
+ {0x0004e4, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e5, {[CaseLower] = 0x0004e5,[CaseTitle] = 0x0004e4,[CaseUpper] = 0x0004e4}, NULL},
+ {0x0004e6, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e7, {[CaseLower] = 0x0004e7,[CaseTitle] = 0x0004e6,[CaseUpper] = 0x0004e6}, NULL},
+ {0x0004e8, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004e9, {[CaseLower] = 0x0004e9,[CaseTitle] = 0x0004e8,[CaseUpper] = 0x0004e8}, NULL},
+ {0x0004ea, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004eb, {[CaseLower] = 0x0004eb,[CaseTitle] = 0x0004ea,[CaseUpper] = 0x0004ea}, NULL},
+ {0x0004ec, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ed, {[CaseLower] = 0x0004ed,[CaseTitle] = 0x0004ec,[CaseUpper] = 0x0004ec}, NULL},
+ {0x0004ee, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004ef, {[CaseLower] = 0x0004ef,[CaseTitle] = 0x0004ee,[CaseUpper] = 0x0004ee}, NULL},
+ {0x0004f0, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f1, {[CaseLower] = 0x0004f1,[CaseTitle] = 0x0004f0,[CaseUpper] = 0x0004f0}, NULL},
+ {0x0004f2, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f3, {[CaseLower] = 0x0004f3,[CaseTitle] = 0x0004f2,[CaseUpper] = 0x0004f2}, NULL},
+ {0x0004f4, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f5, {[CaseLower] = 0x0004f5,[CaseTitle] = 0x0004f4,[CaseUpper] = 0x0004f4}, NULL},
+ {0x0004f6, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f7, {[CaseLower] = 0x0004f7,[CaseTitle] = 0x0004f6,[CaseUpper] = 0x0004f6}, NULL},
+ {0x0004f8, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004f9, {[CaseLower] = 0x0004f9,[CaseTitle] = 0x0004f8,[CaseUpper] = 0x0004f8}, NULL},
+ {0x0004fa, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fb, {[CaseLower] = 0x0004fb,[CaseTitle] = 0x0004fa,[CaseUpper] = 0x0004fa}, NULL},
+ {0x0004fc, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fd, {[CaseLower] = 0x0004fd,[CaseTitle] = 0x0004fc,[CaseUpper] = 0x0004fc}, NULL},
+ {0x0004fe, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x0004ff, {[CaseLower] = 0x0004ff,[CaseTitle] = 0x0004fe,[CaseUpper] = 0x0004fe}, NULL},
+ {0x000500, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000501, {[CaseLower] = 0x000501,[CaseTitle] = 0x000500,[CaseUpper] = 0x000500}, NULL},
+ {0x000502, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000503, {[CaseLower] = 0x000503,[CaseTitle] = 0x000502,[CaseUpper] = 0x000502}, NULL},
+ {0x000504, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000505, {[CaseLower] = 0x000505,[CaseTitle] = 0x000504,[CaseUpper] = 0x000504}, NULL},
+ {0x000506, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000507, {[CaseLower] = 0x000507,[CaseTitle] = 0x000506,[CaseUpper] = 0x000506}, NULL},
+ {0x000508, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x000509, {[CaseLower] = 0x000509,[CaseTitle] = 0x000508,[CaseUpper] = 0x000508}, NULL},
+ {0x00050a, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050b, {[CaseLower] = 0x00050b,[CaseTitle] = 0x00050a,[CaseUpper] = 0x00050a}, NULL},
+ {0x00050c, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050d, {[CaseLower] = 0x00050d,[CaseTitle] = 0x00050c,[CaseUpper] = 0x00050c}, NULL},
+ {0x00050e, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x00050f, {[CaseLower] = 0x00050f,[CaseTitle] = 0x00050e,[CaseUpper] = 0x00050e}, NULL},
+ {0x000510, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000511, {[CaseLower] = 0x000511,[CaseTitle] = 0x000510,[CaseUpper] = 0x000510}, NULL},
+ {0x000512, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000513, {[CaseLower] = 0x000513,[CaseTitle] = 0x000512,[CaseUpper] = 0x000512}, NULL},
+ {0x000514, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000515, {[CaseLower] = 0x000515,[CaseTitle] = 0x000514,[CaseUpper] = 0x000514}, NULL},
+ {0x000516, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000517, {[CaseLower] = 0x000517,[CaseTitle] = 0x000516,[CaseUpper] = 0x000516}, NULL},
+ {0x000518, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x000519, {[CaseLower] = 0x000519,[CaseTitle] = 0x000518,[CaseUpper] = 0x000518}, NULL},
+ {0x00051a, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051b, {[CaseLower] = 0x00051b,[CaseTitle] = 0x00051a,[CaseUpper] = 0x00051a}, NULL},
+ {0x00051c, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051d, {[CaseLower] = 0x00051d,[CaseTitle] = 0x00051c,[CaseUpper] = 0x00051c}, NULL},
+ {0x00051e, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x00051f, {[CaseLower] = 0x00051f,[CaseTitle] = 0x00051e,[CaseUpper] = 0x00051e}, NULL},
+ {0x000520, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000521, {[CaseLower] = 0x000521,[CaseTitle] = 0x000520,[CaseUpper] = 0x000520}, NULL},
+ {0x000522, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000523, {[CaseLower] = 0x000523,[CaseTitle] = 0x000522,[CaseUpper] = 0x000522}, NULL},
+ {0x000524, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000525, {[CaseLower] = 0x000525,[CaseTitle] = 0x000524,[CaseUpper] = 0x000524}, NULL},
+ {0x000526, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000527, {[CaseLower] = 0x000527,[CaseTitle] = 0x000526,[CaseUpper] = 0x000526}, NULL},
+ {0x000528, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x000529, {[CaseLower] = 0x000529,[CaseTitle] = 0x000528,[CaseUpper] = 0x000528}, NULL},
+ {0x00052a, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052b, {[CaseLower] = 0x00052b,[CaseTitle] = 0x00052a,[CaseUpper] = 0x00052a}, NULL},
+ {0x00052c, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052d, {[CaseLower] = 0x00052d,[CaseTitle] = 0x00052c,[CaseUpper] = 0x00052c}, NULL},
+ {0x00052e, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x00052f, {[CaseLower] = 0x00052f,[CaseTitle] = 0x00052e,[CaseUpper] = 0x00052e}, NULL},
+ {0x000531, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000532, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000533, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000534, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000535, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000536, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000537, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000538, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000539, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00053a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00053b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00053c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00053d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00053e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00053f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000540, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000541, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000542, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000543, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000544, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000545, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000546, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000547, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000548, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000549, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00054a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00054b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00054c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00054d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00054e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00054f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000550, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000551, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000552, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000553, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000554, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000555, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000556, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000561, {[CaseLower] = 0x000561,[CaseTitle] = 0x000531,[CaseUpper] = 0x000531}, NULL},
+ {0x000562, {[CaseLower] = 0x000562,[CaseTitle] = 0x000532,[CaseUpper] = 0x000532}, NULL},
+ {0x000563, {[CaseLower] = 0x000563,[CaseTitle] = 0x000533,[CaseUpper] = 0x000533}, NULL},
+ {0x000564, {[CaseLower] = 0x000564,[CaseTitle] = 0x000534,[CaseUpper] = 0x000534}, NULL},
+ {0x000565, {[CaseLower] = 0x000565,[CaseTitle] = 0x000535,[CaseUpper] = 0x000535}, NULL},
+ {0x000566, {[CaseLower] = 0x000566,[CaseTitle] = 0x000536,[CaseUpper] = 0x000536}, NULL},
+ {0x000567, {[CaseLower] = 0x000567,[CaseTitle] = 0x000537,[CaseUpper] = 0x000537}, NULL},
+ {0x000568, {[CaseLower] = 0x000568,[CaseTitle] = 0x000538,[CaseUpper] = 0x000538}, NULL},
+ {0x000569, {[CaseLower] = 0x000569,[CaseTitle] = 0x000539,[CaseUpper] = 0x000539}, NULL},
+ {0x00056a, {[CaseLower] = 0x00056a,[CaseTitle] = 0x00053a,[CaseUpper] = 0x00053a}, NULL},
+ {0x00056b, {[CaseLower] = 0x00056b,[CaseTitle] = 0x00053b,[CaseUpper] = 0x00053b}, NULL},
+ {0x00056c, {[CaseLower] = 0x00056c,[CaseTitle] = 0x00053c,[CaseUpper] = 0x00053c}, NULL},
+ {0x00056d, {[CaseLower] = 0x00056d,[CaseTitle] = 0x00053d,[CaseUpper] = 0x00053d}, NULL},
+ {0x00056e, {[CaseLower] = 0x00056e,[CaseTitle] = 0x00053e,[CaseUpper] = 0x00053e}, NULL},
+ {0x00056f, {[CaseLower] = 0x00056f,[CaseTitle] = 0x00053f,[CaseUpper] = 0x00053f}, NULL},
+ {0x000570, {[CaseLower] = 0x000570,[CaseTitle] = 0x000540,[CaseUpper] = 0x000540}, NULL},
+ {0x000571, {[CaseLower] = 0x000571,[CaseTitle] = 0x000541,[CaseUpper] = 0x000541}, NULL},
+ {0x000572, {[CaseLower] = 0x000572,[CaseTitle] = 0x000542,[CaseUpper] = 0x000542}, NULL},
+ {0x000573, {[CaseLower] = 0x000573,[CaseTitle] = 0x000543,[CaseUpper] = 0x000543}, NULL},
+ {0x000574, {[CaseLower] = 0x000574,[CaseTitle] = 0x000544,[CaseUpper] = 0x000544}, NULL},
+ {0x000575, {[CaseLower] = 0x000575,[CaseTitle] = 0x000545,[CaseUpper] = 0x000545}, NULL},
+ {0x000576, {[CaseLower] = 0x000576,[CaseTitle] = 0x000546,[CaseUpper] = 0x000546}, NULL},
+ {0x000577, {[CaseLower] = 0x000577,[CaseTitle] = 0x000547,[CaseUpper] = 0x000547}, NULL},
+ {0x000578, {[CaseLower] = 0x000578,[CaseTitle] = 0x000548,[CaseUpper] = 0x000548}, NULL},
+ {0x000579, {[CaseLower] = 0x000579,[CaseTitle] = 0x000549,[CaseUpper] = 0x000549}, NULL},
+ {0x00057a, {[CaseLower] = 0x00057a,[CaseTitle] = 0x00054a,[CaseUpper] = 0x00054a}, NULL},
+ {0x00057b, {[CaseLower] = 0x00057b,[CaseTitle] = 0x00054b,[CaseUpper] = 0x00054b}, NULL},
+ {0x00057c, {[CaseLower] = 0x00057c,[CaseTitle] = 0x00054c,[CaseUpper] = 0x00054c}, NULL},
+ {0x00057d, {[CaseLower] = 0x00057d,[CaseTitle] = 0x00054d,[CaseUpper] = 0x00054d}, NULL},
+ {0x00057e, {[CaseLower] = 0x00057e,[CaseTitle] = 0x00054e,[CaseUpper] = 0x00054e}, NULL},
+ {0x00057f, {[CaseLower] = 0x00057f,[CaseTitle] = 0x00054f,[CaseUpper] = 0x00054f}, NULL},
+ {0x000580, {[CaseLower] = 0x000580,[CaseTitle] = 0x000550,[CaseUpper] = 0x000550}, NULL},
+ {0x000581, {[CaseLower] = 0x000581,[CaseTitle] = 0x000551,[CaseUpper] = 0x000551}, NULL},
+ {0x000582, {[CaseLower] = 0x000582,[CaseTitle] = 0x000552,[CaseUpper] = 0x000552}, NULL},
+ {0x000583, {[CaseLower] = 0x000583,[CaseTitle] = 0x000553,[CaseUpper] = 0x000553}, NULL},
+ {0x000584, {[CaseLower] = 0x000584,[CaseTitle] = 0x000554,[CaseUpper] = 0x000554}, NULL},
+ {0x000585, {[CaseLower] = 0x000585,[CaseTitle] = 0x000555,[CaseUpper] = 0x000555}, NULL},
+ {0x000586, {[CaseLower] = 0x000586,[CaseTitle] = 0x000556,[CaseUpper] = 0x000556}, NULL},
+ {0x000587, {[CaseLower] = 0x000587,[CaseTitle] = 0x000587,[CaseUpper] = 0x000587}, &special_case[7]},
+ {0x0010a0, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x0010a1, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x0010a2, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x0010a3, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x0010a4, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x0010a5, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x0010a6, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x0010a7, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x0010a8, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x0010a9, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x0010aa, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x0010ab, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x0010ac, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x0010ad, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x0010ae, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x0010af, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x0010b0, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x0010b1, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x0010b2, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x0010b3, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x0010b4, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x0010b5, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x0010b6, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x0010b7, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x0010b8, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x0010b9, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x0010ba, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x0010bb, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x0010bc, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x0010bd, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x0010be, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x0010bf, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x0010c0, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x0010c1, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x0010c2, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x0010c3, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x0010c4, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x0010c5, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x0010c7, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x0010cd, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x0010d0, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x0010d0,[CaseUpper] = 0x001c90}, NULL},
+ {0x0010d1, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x0010d1,[CaseUpper] = 0x001c91}, NULL},
+ {0x0010d2, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x0010d2,[CaseUpper] = 0x001c92}, NULL},
+ {0x0010d3, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x0010d3,[CaseUpper] = 0x001c93}, NULL},
+ {0x0010d4, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x0010d4,[CaseUpper] = 0x001c94}, NULL},
+ {0x0010d5, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x0010d5,[CaseUpper] = 0x001c95}, NULL},
+ {0x0010d6, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x0010d6,[CaseUpper] = 0x001c96}, NULL},
+ {0x0010d7, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x0010d7,[CaseUpper] = 0x001c97}, NULL},
+ {0x0010d8, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x0010d8,[CaseUpper] = 0x001c98}, NULL},
+ {0x0010d9, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x0010d9,[CaseUpper] = 0x001c99}, NULL},
+ {0x0010da, {[CaseLower] = 0x0010da,[CaseTitle] = 0x0010da,[CaseUpper] = 0x001c9a}, NULL},
+ {0x0010db, {[CaseLower] = 0x0010db,[CaseTitle] = 0x0010db,[CaseUpper] = 0x001c9b}, NULL},
+ {0x0010dc, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x0010dc,[CaseUpper] = 0x001c9c}, NULL},
+ {0x0010dd, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x0010dd,[CaseUpper] = 0x001c9d}, NULL},
+ {0x0010de, {[CaseLower] = 0x0010de,[CaseTitle] = 0x0010de,[CaseUpper] = 0x001c9e}, NULL},
+ {0x0010df, {[CaseLower] = 0x0010df,[CaseTitle] = 0x0010df,[CaseUpper] = 0x001c9f}, NULL},
+ {0x0010e0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x0010e0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x0010e1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x0010e1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x0010e2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x0010e2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x0010e3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x0010e3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x0010e4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x0010e4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x0010e5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x0010e5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x0010e6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x0010e6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x0010e7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x0010e7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x0010e8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x0010e8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x0010e9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x0010e9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x0010ea, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x0010ea,[CaseUpper] = 0x001caa}, NULL},
+ {0x0010eb, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x0010eb,[CaseUpper] = 0x001cab}, NULL},
+ {0x0010ec, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x0010ec,[CaseUpper] = 0x001cac}, NULL},
+ {0x0010ed, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x0010ed,[CaseUpper] = 0x001cad}, NULL},
+ {0x0010ee, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x0010ee,[CaseUpper] = 0x001cae}, NULL},
+ {0x0010ef, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x0010ef,[CaseUpper] = 0x001caf}, NULL},
+ {0x0010f0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x0010f0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x0010f1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x0010f1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x0010f2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x0010f2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x0010f3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x0010f3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x0010f4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x0010f4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x0010f5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x0010f5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x0010f6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x0010f6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x0010f7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x0010f7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x0010f8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x0010f8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x0010f9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x0010f9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x0010fa, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x0010fa,[CaseUpper] = 0x001cba}, NULL},
+ {0x0010fd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x0010fd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x0010fe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x0010fe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x0010ff, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x0010ff,[CaseUpper] = 0x001cbf}, NULL},
+ {0x0013a0, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x0013a1, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x0013a2, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x0013a3, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x0013a4, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x0013a5, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x0013a6, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x0013a7, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x0013a8, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x0013a9, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x0013aa, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x0013ab, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x0013ac, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x0013ad, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x0013ae, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x0013af, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x0013b0, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x0013b1, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x0013b2, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x0013b3, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x0013b4, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x0013b5, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x0013b6, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x0013b7, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x0013b8, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x0013b9, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x0013ba, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x0013bb, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x0013bc, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x0013bd, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x0013be, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x0013bf, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x0013c0, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x0013c1, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x0013c2, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x0013c3, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x0013c4, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x0013c5, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x0013c6, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x0013c7, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x0013c8, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x0013c9, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x0013ca, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x0013cb, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x0013cc, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x0013cd, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x0013ce, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x0013cf, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x0013d0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x0013d1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x0013d2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x0013d3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x0013d4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x0013d5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x0013d6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x0013d7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x0013d8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x0013d9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x0013da, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x0013db, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x0013dc, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x0013dd, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x0013de, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x0013df, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x0013e0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x0013e1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x0013e2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x0013e3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x0013e4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x0013e5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x0013e6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x0013e7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x0013e8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x0013e9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x0013ea, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x0013eb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x0013ec, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x0013ed, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x0013ee, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x0013ef, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x0013f0, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f1, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013f2, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013f3, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013f4, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013f5, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x0013f8, {[CaseLower] = 0x0013f8,[CaseTitle] = 0x0013f0,[CaseUpper] = 0x0013f0}, NULL},
+ {0x0013f9, {[CaseLower] = 0x0013f9,[CaseTitle] = 0x0013f1,[CaseUpper] = 0x0013f1}, NULL},
+ {0x0013fa, {[CaseLower] = 0x0013fa,[CaseTitle] = 0x0013f2,[CaseUpper] = 0x0013f2}, NULL},
+ {0x0013fb, {[CaseLower] = 0x0013fb,[CaseTitle] = 0x0013f3,[CaseUpper] = 0x0013f3}, NULL},
+ {0x0013fc, {[CaseLower] = 0x0013fc,[CaseTitle] = 0x0013f4,[CaseUpper] = 0x0013f4}, NULL},
+ {0x0013fd, {[CaseLower] = 0x0013fd,[CaseTitle] = 0x0013f5,[CaseUpper] = 0x0013f5}, NULL},
+ {0x001c80, {[CaseLower] = 0x001c80,[CaseTitle] = 0x000412,[CaseUpper] = 0x000412}, NULL},
+ {0x001c81, {[CaseLower] = 0x001c81,[CaseTitle] = 0x000414,[CaseUpper] = 0x000414}, NULL},
+ {0x001c82, {[CaseLower] = 0x001c82,[CaseTitle] = 0x00041e,[CaseUpper] = 0x00041e}, NULL},
+ {0x001c83, {[CaseLower] = 0x001c83,[CaseTitle] = 0x000421,[CaseUpper] = 0x000421}, NULL},
+ {0x001c84, {[CaseLower] = 0x001c84,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c85, {[CaseLower] = 0x001c85,[CaseTitle] = 0x000422,[CaseUpper] = 0x000422}, NULL},
+ {0x001c86, {[CaseLower] = 0x001c86,[CaseTitle] = 0x00042a,[CaseUpper] = 0x00042a}, NULL},
+ {0x001c87, {[CaseLower] = 0x001c87,[CaseTitle] = 0x000462,[CaseUpper] = 0x000462}, NULL},
+ {0x001c88, {[CaseLower] = 0x001c88,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x001c90, {[CaseLower] = 0x0010d0,[CaseTitle] = 0x001c90,[CaseUpper] = 0x001c90}, NULL},
+ {0x001c91, {[CaseLower] = 0x0010d1,[CaseTitle] = 0x001c91,[CaseUpper] = 0x001c91}, NULL},
+ {0x001c92, {[CaseLower] = 0x0010d2,[CaseTitle] = 0x001c92,[CaseUpper] = 0x001c92}, NULL},
+ {0x001c93, {[CaseLower] = 0x0010d3,[CaseTitle] = 0x001c93,[CaseUpper] = 0x001c93}, NULL},
+ {0x001c94, {[CaseLower] = 0x0010d4,[CaseTitle] = 0x001c94,[CaseUpper] = 0x001c94}, NULL},
+ {0x001c95, {[CaseLower] = 0x0010d5,[CaseTitle] = 0x001c95,[CaseUpper] = 0x001c95}, NULL},
+ {0x001c96, {[CaseLower] = 0x0010d6,[CaseTitle] = 0x001c96,[CaseUpper] = 0x001c96}, NULL},
+ {0x001c97, {[CaseLower] = 0x0010d7,[CaseTitle] = 0x001c97,[CaseUpper] = 0x001c97}, NULL},
+ {0x001c98, {[CaseLower] = 0x0010d8,[CaseTitle] = 0x001c98,[CaseUpper] = 0x001c98}, NULL},
+ {0x001c99, {[CaseLower] = 0x0010d9,[CaseTitle] = 0x001c99,[CaseUpper] = 0x001c99}, NULL},
+ {0x001c9a, {[CaseLower] = 0x0010da,[CaseTitle] = 0x001c9a,[CaseUpper] = 0x001c9a}, NULL},
+ {0x001c9b, {[CaseLower] = 0x0010db,[CaseTitle] = 0x001c9b,[CaseUpper] = 0x001c9b}, NULL},
+ {0x001c9c, {[CaseLower] = 0x0010dc,[CaseTitle] = 0x001c9c,[CaseUpper] = 0x001c9c}, NULL},
+ {0x001c9d, {[CaseLower] = 0x0010dd,[CaseTitle] = 0x001c9d,[CaseUpper] = 0x001c9d}, NULL},
+ {0x001c9e, {[CaseLower] = 0x0010de,[CaseTitle] = 0x001c9e,[CaseUpper] = 0x001c9e}, NULL},
+ {0x001c9f, {[CaseLower] = 0x0010df,[CaseTitle] = 0x001c9f,[CaseUpper] = 0x001c9f}, NULL},
+ {0x001ca0, {[CaseLower] = 0x0010e0,[CaseTitle] = 0x001ca0,[CaseUpper] = 0x001ca0}, NULL},
+ {0x001ca1, {[CaseLower] = 0x0010e1,[CaseTitle] = 0x001ca1,[CaseUpper] = 0x001ca1}, NULL},
+ {0x001ca2, {[CaseLower] = 0x0010e2,[CaseTitle] = 0x001ca2,[CaseUpper] = 0x001ca2}, NULL},
+ {0x001ca3, {[CaseLower] = 0x0010e3,[CaseTitle] = 0x001ca3,[CaseUpper] = 0x001ca3}, NULL},
+ {0x001ca4, {[CaseLower] = 0x0010e4,[CaseTitle] = 0x001ca4,[CaseUpper] = 0x001ca4}, NULL},
+ {0x001ca5, {[CaseLower] = 0x0010e5,[CaseTitle] = 0x001ca5,[CaseUpper] = 0x001ca5}, NULL},
+ {0x001ca6, {[CaseLower] = 0x0010e6,[CaseTitle] = 0x001ca6,[CaseUpper] = 0x001ca6}, NULL},
+ {0x001ca7, {[CaseLower] = 0x0010e7,[CaseTitle] = 0x001ca7,[CaseUpper] = 0x001ca7}, NULL},
+ {0x001ca8, {[CaseLower] = 0x0010e8,[CaseTitle] = 0x001ca8,[CaseUpper] = 0x001ca8}, NULL},
+ {0x001ca9, {[CaseLower] = 0x0010e9,[CaseTitle] = 0x001ca9,[CaseUpper] = 0x001ca9}, NULL},
+ {0x001caa, {[CaseLower] = 0x0010ea,[CaseTitle] = 0x001caa,[CaseUpper] = 0x001caa}, NULL},
+ {0x001cab, {[CaseLower] = 0x0010eb,[CaseTitle] = 0x001cab,[CaseUpper] = 0x001cab}, NULL},
+ {0x001cac, {[CaseLower] = 0x0010ec,[CaseTitle] = 0x001cac,[CaseUpper] = 0x001cac}, NULL},
+ {0x001cad, {[CaseLower] = 0x0010ed,[CaseTitle] = 0x001cad,[CaseUpper] = 0x001cad}, NULL},
+ {0x001cae, {[CaseLower] = 0x0010ee,[CaseTitle] = 0x001cae,[CaseUpper] = 0x001cae}, NULL},
+ {0x001caf, {[CaseLower] = 0x0010ef,[CaseTitle] = 0x001caf,[CaseUpper] = 0x001caf}, NULL},
+ {0x001cb0, {[CaseLower] = 0x0010f0,[CaseTitle] = 0x001cb0,[CaseUpper] = 0x001cb0}, NULL},
+ {0x001cb1, {[CaseLower] = 0x0010f1,[CaseTitle] = 0x001cb1,[CaseUpper] = 0x001cb1}, NULL},
+ {0x001cb2, {[CaseLower] = 0x0010f2,[CaseTitle] = 0x001cb2,[CaseUpper] = 0x001cb2}, NULL},
+ {0x001cb3, {[CaseLower] = 0x0010f3,[CaseTitle] = 0x001cb3,[CaseUpper] = 0x001cb3}, NULL},
+ {0x001cb4, {[CaseLower] = 0x0010f4,[CaseTitle] = 0x001cb4,[CaseUpper] = 0x001cb4}, NULL},
+ {0x001cb5, {[CaseLower] = 0x0010f5,[CaseTitle] = 0x001cb5,[CaseUpper] = 0x001cb5}, NULL},
+ {0x001cb6, {[CaseLower] = 0x0010f6,[CaseTitle] = 0x001cb6,[CaseUpper] = 0x001cb6}, NULL},
+ {0x001cb7, {[CaseLower] = 0x0010f7,[CaseTitle] = 0x001cb7,[CaseUpper] = 0x001cb7}, NULL},
+ {0x001cb8, {[CaseLower] = 0x0010f8,[CaseTitle] = 0x001cb8,[CaseUpper] = 0x001cb8}, NULL},
+ {0x001cb9, {[CaseLower] = 0x0010f9,[CaseTitle] = 0x001cb9,[CaseUpper] = 0x001cb9}, NULL},
+ {0x001cba, {[CaseLower] = 0x0010fa,[CaseTitle] = 0x001cba,[CaseUpper] = 0x001cba}, NULL},
+ {0x001cbd, {[CaseLower] = 0x0010fd,[CaseTitle] = 0x001cbd,[CaseUpper] = 0x001cbd}, NULL},
+ {0x001cbe, {[CaseLower] = 0x0010fe,[CaseTitle] = 0x001cbe,[CaseUpper] = 0x001cbe}, NULL},
+ {0x001cbf, {[CaseLower] = 0x0010ff,[CaseTitle] = 0x001cbf,[CaseUpper] = 0x001cbf}, NULL},
+ {0x001d79, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x001d7d, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x001d8e, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x001e00, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e01, {[CaseLower] = 0x001e01,[CaseTitle] = 0x001e00,[CaseUpper] = 0x001e00}, NULL},
+ {0x001e02, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e03, {[CaseLower] = 0x001e03,[CaseTitle] = 0x001e02,[CaseUpper] = 0x001e02}, NULL},
+ {0x001e04, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e05, {[CaseLower] = 0x001e05,[CaseTitle] = 0x001e04,[CaseUpper] = 0x001e04}, NULL},
+ {0x001e06, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e07, {[CaseLower] = 0x001e07,[CaseTitle] = 0x001e06,[CaseUpper] = 0x001e06}, NULL},
+ {0x001e08, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e09, {[CaseLower] = 0x001e09,[CaseTitle] = 0x001e08,[CaseUpper] = 0x001e08}, NULL},
+ {0x001e0a, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0b, {[CaseLower] = 0x001e0b,[CaseTitle] = 0x001e0a,[CaseUpper] = 0x001e0a}, NULL},
+ {0x001e0c, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0d, {[CaseLower] = 0x001e0d,[CaseTitle] = 0x001e0c,[CaseUpper] = 0x001e0c}, NULL},
+ {0x001e0e, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e0f, {[CaseLower] = 0x001e0f,[CaseTitle] = 0x001e0e,[CaseUpper] = 0x001e0e}, NULL},
+ {0x001e10, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e11, {[CaseLower] = 0x001e11,[CaseTitle] = 0x001e10,[CaseUpper] = 0x001e10}, NULL},
+ {0x001e12, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e13, {[CaseLower] = 0x001e13,[CaseTitle] = 0x001e12,[CaseUpper] = 0x001e12}, NULL},
+ {0x001e14, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e15, {[CaseLower] = 0x001e15,[CaseTitle] = 0x001e14,[CaseUpper] = 0x001e14}, NULL},
+ {0x001e16, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e17, {[CaseLower] = 0x001e17,[CaseTitle] = 0x001e16,[CaseUpper] = 0x001e16}, NULL},
+ {0x001e18, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e19, {[CaseLower] = 0x001e19,[CaseTitle] = 0x001e18,[CaseUpper] = 0x001e18}, NULL},
+ {0x001e1a, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1b, {[CaseLower] = 0x001e1b,[CaseTitle] = 0x001e1a,[CaseUpper] = 0x001e1a}, NULL},
+ {0x001e1c, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1d, {[CaseLower] = 0x001e1d,[CaseTitle] = 0x001e1c,[CaseUpper] = 0x001e1c}, NULL},
+ {0x001e1e, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e1f, {[CaseLower] = 0x001e1f,[CaseTitle] = 0x001e1e,[CaseUpper] = 0x001e1e}, NULL},
+ {0x001e20, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e21, {[CaseLower] = 0x001e21,[CaseTitle] = 0x001e20,[CaseUpper] = 0x001e20}, NULL},
+ {0x001e22, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e23, {[CaseLower] = 0x001e23,[CaseTitle] = 0x001e22,[CaseUpper] = 0x001e22}, NULL},
+ {0x001e24, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e25, {[CaseLower] = 0x001e25,[CaseTitle] = 0x001e24,[CaseUpper] = 0x001e24}, NULL},
+ {0x001e26, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e27, {[CaseLower] = 0x001e27,[CaseTitle] = 0x001e26,[CaseUpper] = 0x001e26}, NULL},
+ {0x001e28, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e29, {[CaseLower] = 0x001e29,[CaseTitle] = 0x001e28,[CaseUpper] = 0x001e28}, NULL},
+ {0x001e2a, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2b, {[CaseLower] = 0x001e2b,[CaseTitle] = 0x001e2a,[CaseUpper] = 0x001e2a}, NULL},
+ {0x001e2c, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2d, {[CaseLower] = 0x001e2d,[CaseTitle] = 0x001e2c,[CaseUpper] = 0x001e2c}, NULL},
+ {0x001e2e, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e2f, {[CaseLower] = 0x001e2f,[CaseTitle] = 0x001e2e,[CaseUpper] = 0x001e2e}, NULL},
+ {0x001e30, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e31, {[CaseLower] = 0x001e31,[CaseTitle] = 0x001e30,[CaseUpper] = 0x001e30}, NULL},
+ {0x001e32, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e33, {[CaseLower] = 0x001e33,[CaseTitle] = 0x001e32,[CaseUpper] = 0x001e32}, NULL},
+ {0x001e34, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e35, {[CaseLower] = 0x001e35,[CaseTitle] = 0x001e34,[CaseUpper] = 0x001e34}, NULL},
+ {0x001e36, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e37, {[CaseLower] = 0x001e37,[CaseTitle] = 0x001e36,[CaseUpper] = 0x001e36}, NULL},
+ {0x001e38, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e39, {[CaseLower] = 0x001e39,[CaseTitle] = 0x001e38,[CaseUpper] = 0x001e38}, NULL},
+ {0x001e3a, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3b, {[CaseLower] = 0x001e3b,[CaseTitle] = 0x001e3a,[CaseUpper] = 0x001e3a}, NULL},
+ {0x001e3c, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3d, {[CaseLower] = 0x001e3d,[CaseTitle] = 0x001e3c,[CaseUpper] = 0x001e3c}, NULL},
+ {0x001e3e, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e3f, {[CaseLower] = 0x001e3f,[CaseTitle] = 0x001e3e,[CaseUpper] = 0x001e3e}, NULL},
+ {0x001e40, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e41, {[CaseLower] = 0x001e41,[CaseTitle] = 0x001e40,[CaseUpper] = 0x001e40}, NULL},
+ {0x001e42, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e43, {[CaseLower] = 0x001e43,[CaseTitle] = 0x001e42,[CaseUpper] = 0x001e42}, NULL},
+ {0x001e44, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e45, {[CaseLower] = 0x001e45,[CaseTitle] = 0x001e44,[CaseUpper] = 0x001e44}, NULL},
+ {0x001e46, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e47, {[CaseLower] = 0x001e47,[CaseTitle] = 0x001e46,[CaseUpper] = 0x001e46}, NULL},
+ {0x001e48, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e49, {[CaseLower] = 0x001e49,[CaseTitle] = 0x001e48,[CaseUpper] = 0x001e48}, NULL},
+ {0x001e4a, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4b, {[CaseLower] = 0x001e4b,[CaseTitle] = 0x001e4a,[CaseUpper] = 0x001e4a}, NULL},
+ {0x001e4c, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4d, {[CaseLower] = 0x001e4d,[CaseTitle] = 0x001e4c,[CaseUpper] = 0x001e4c}, NULL},
+ {0x001e4e, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e4f, {[CaseLower] = 0x001e4f,[CaseTitle] = 0x001e4e,[CaseUpper] = 0x001e4e}, NULL},
+ {0x001e50, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e51, {[CaseLower] = 0x001e51,[CaseTitle] = 0x001e50,[CaseUpper] = 0x001e50}, NULL},
+ {0x001e52, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e53, {[CaseLower] = 0x001e53,[CaseTitle] = 0x001e52,[CaseUpper] = 0x001e52}, NULL},
+ {0x001e54, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e55, {[CaseLower] = 0x001e55,[CaseTitle] = 0x001e54,[CaseUpper] = 0x001e54}, NULL},
+ {0x001e56, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e57, {[CaseLower] = 0x001e57,[CaseTitle] = 0x001e56,[CaseUpper] = 0x001e56}, NULL},
+ {0x001e58, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e59, {[CaseLower] = 0x001e59,[CaseTitle] = 0x001e58,[CaseUpper] = 0x001e58}, NULL},
+ {0x001e5a, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5b, {[CaseLower] = 0x001e5b,[CaseTitle] = 0x001e5a,[CaseUpper] = 0x001e5a}, NULL},
+ {0x001e5c, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5d, {[CaseLower] = 0x001e5d,[CaseTitle] = 0x001e5c,[CaseUpper] = 0x001e5c}, NULL},
+ {0x001e5e, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e5f, {[CaseLower] = 0x001e5f,[CaseTitle] = 0x001e5e,[CaseUpper] = 0x001e5e}, NULL},
+ {0x001e60, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e61, {[CaseLower] = 0x001e61,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e62, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e63, {[CaseLower] = 0x001e63,[CaseTitle] = 0x001e62,[CaseUpper] = 0x001e62}, NULL},
+ {0x001e64, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e65, {[CaseLower] = 0x001e65,[CaseTitle] = 0x001e64,[CaseUpper] = 0x001e64}, NULL},
+ {0x001e66, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e67, {[CaseLower] = 0x001e67,[CaseTitle] = 0x001e66,[CaseUpper] = 0x001e66}, NULL},
+ {0x001e68, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e69, {[CaseLower] = 0x001e69,[CaseTitle] = 0x001e68,[CaseUpper] = 0x001e68}, NULL},
+ {0x001e6a, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6b, {[CaseLower] = 0x001e6b,[CaseTitle] = 0x001e6a,[CaseUpper] = 0x001e6a}, NULL},
+ {0x001e6c, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6d, {[CaseLower] = 0x001e6d,[CaseTitle] = 0x001e6c,[CaseUpper] = 0x001e6c}, NULL},
+ {0x001e6e, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e6f, {[CaseLower] = 0x001e6f,[CaseTitle] = 0x001e6e,[CaseUpper] = 0x001e6e}, NULL},
+ {0x001e70, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e71, {[CaseLower] = 0x001e71,[CaseTitle] = 0x001e70,[CaseUpper] = 0x001e70}, NULL},
+ {0x001e72, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e73, {[CaseLower] = 0x001e73,[CaseTitle] = 0x001e72,[CaseUpper] = 0x001e72}, NULL},
+ {0x001e74, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e75, {[CaseLower] = 0x001e75,[CaseTitle] = 0x001e74,[CaseUpper] = 0x001e74}, NULL},
+ {0x001e76, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e77, {[CaseLower] = 0x001e77,[CaseTitle] = 0x001e76,[CaseUpper] = 0x001e76}, NULL},
+ {0x001e78, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e79, {[CaseLower] = 0x001e79,[CaseTitle] = 0x001e78,[CaseUpper] = 0x001e78}, NULL},
+ {0x001e7a, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7b, {[CaseLower] = 0x001e7b,[CaseTitle] = 0x001e7a,[CaseUpper] = 0x001e7a}, NULL},
+ {0x001e7c, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7d, {[CaseLower] = 0x001e7d,[CaseTitle] = 0x001e7c,[CaseUpper] = 0x001e7c}, NULL},
+ {0x001e7e, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e7f, {[CaseLower] = 0x001e7f,[CaseTitle] = 0x001e7e,[CaseUpper] = 0x001e7e}, NULL},
+ {0x001e80, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e81, {[CaseLower] = 0x001e81,[CaseTitle] = 0x001e80,[CaseUpper] = 0x001e80}, NULL},
+ {0x001e82, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e83, {[CaseLower] = 0x001e83,[CaseTitle] = 0x001e82,[CaseUpper] = 0x001e82}, NULL},
+ {0x001e84, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e85, {[CaseLower] = 0x001e85,[CaseTitle] = 0x001e84,[CaseUpper] = 0x001e84}, NULL},
+ {0x001e86, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e87, {[CaseLower] = 0x001e87,[CaseTitle] = 0x001e86,[CaseUpper] = 0x001e86}, NULL},
+ {0x001e88, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e89, {[CaseLower] = 0x001e89,[CaseTitle] = 0x001e88,[CaseUpper] = 0x001e88}, NULL},
+ {0x001e8a, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8b, {[CaseLower] = 0x001e8b,[CaseTitle] = 0x001e8a,[CaseUpper] = 0x001e8a}, NULL},
+ {0x001e8c, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8d, {[CaseLower] = 0x001e8d,[CaseTitle] = 0x001e8c,[CaseUpper] = 0x001e8c}, NULL},
+ {0x001e8e, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e8f, {[CaseLower] = 0x001e8f,[CaseTitle] = 0x001e8e,[CaseUpper] = 0x001e8e}, NULL},
+ {0x001e90, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e91, {[CaseLower] = 0x001e91,[CaseTitle] = 0x001e90,[CaseUpper] = 0x001e90}, NULL},
+ {0x001e92, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e93, {[CaseLower] = 0x001e93,[CaseTitle] = 0x001e92,[CaseUpper] = 0x001e92}, NULL},
+ {0x001e94, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e95, {[CaseLower] = 0x001e95,[CaseTitle] = 0x001e94,[CaseUpper] = 0x001e94}, NULL},
+ {0x001e96, {[CaseLower] = 0x001e96,[CaseTitle] = 0x001e96,[CaseUpper] = 0x001e96}, &special_case[8]},
+ {0x001e97, {[CaseLower] = 0x001e97,[CaseTitle] = 0x001e97,[CaseUpper] = 0x001e97}, &special_case[9]},
+ {0x001e98, {[CaseLower] = 0x001e98,[CaseTitle] = 0x001e98,[CaseUpper] = 0x001e98}, &special_case[10]},
+ {0x001e99, {[CaseLower] = 0x001e99,[CaseTitle] = 0x001e99,[CaseUpper] = 0x001e99}, &special_case[11]},
+ {0x001e9a, {[CaseLower] = 0x001e9a,[CaseTitle] = 0x001e9a,[CaseUpper] = 0x001e9a}, &special_case[12]},
+ {0x001e9b, {[CaseLower] = 0x001e9b,[CaseTitle] = 0x001e60,[CaseUpper] = 0x001e60}, NULL},
+ {0x001e9e, {[CaseLower] = 0x0000df,[CaseTitle] = 0x001e9e,[CaseUpper] = 0x001e9e}, NULL},
+ {0x001ea0, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea1, {[CaseLower] = 0x001ea1,[CaseTitle] = 0x001ea0,[CaseUpper] = 0x001ea0}, NULL},
+ {0x001ea2, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea3, {[CaseLower] = 0x001ea3,[CaseTitle] = 0x001ea2,[CaseUpper] = 0x001ea2}, NULL},
+ {0x001ea4, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea5, {[CaseLower] = 0x001ea5,[CaseTitle] = 0x001ea4,[CaseUpper] = 0x001ea4}, NULL},
+ {0x001ea6, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea7, {[CaseLower] = 0x001ea7,[CaseTitle] = 0x001ea6,[CaseUpper] = 0x001ea6}, NULL},
+ {0x001ea8, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001ea9, {[CaseLower] = 0x001ea9,[CaseTitle] = 0x001ea8,[CaseUpper] = 0x001ea8}, NULL},
+ {0x001eaa, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eab, {[CaseLower] = 0x001eab,[CaseTitle] = 0x001eaa,[CaseUpper] = 0x001eaa}, NULL},
+ {0x001eac, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001ead, {[CaseLower] = 0x001ead,[CaseTitle] = 0x001eac,[CaseUpper] = 0x001eac}, NULL},
+ {0x001eae, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eaf, {[CaseLower] = 0x001eaf,[CaseTitle] = 0x001eae,[CaseUpper] = 0x001eae}, NULL},
+ {0x001eb0, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb1, {[CaseLower] = 0x001eb1,[CaseTitle] = 0x001eb0,[CaseUpper] = 0x001eb0}, NULL},
+ {0x001eb2, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb3, {[CaseLower] = 0x001eb3,[CaseTitle] = 0x001eb2,[CaseUpper] = 0x001eb2}, NULL},
+ {0x001eb4, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb5, {[CaseLower] = 0x001eb5,[CaseTitle] = 0x001eb4,[CaseUpper] = 0x001eb4}, NULL},
+ {0x001eb6, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb7, {[CaseLower] = 0x001eb7,[CaseTitle] = 0x001eb6,[CaseUpper] = 0x001eb6}, NULL},
+ {0x001eb8, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eb9, {[CaseLower] = 0x001eb9,[CaseTitle] = 0x001eb8,[CaseUpper] = 0x001eb8}, NULL},
+ {0x001eba, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebb, {[CaseLower] = 0x001ebb,[CaseTitle] = 0x001eba,[CaseUpper] = 0x001eba}, NULL},
+ {0x001ebc, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebd, {[CaseLower] = 0x001ebd,[CaseTitle] = 0x001ebc,[CaseUpper] = 0x001ebc}, NULL},
+ {0x001ebe, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ebf, {[CaseLower] = 0x001ebf,[CaseTitle] = 0x001ebe,[CaseUpper] = 0x001ebe}, NULL},
+ {0x001ec0, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec1, {[CaseLower] = 0x001ec1,[CaseTitle] = 0x001ec0,[CaseUpper] = 0x001ec0}, NULL},
+ {0x001ec2, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec3, {[CaseLower] = 0x001ec3,[CaseTitle] = 0x001ec2,[CaseUpper] = 0x001ec2}, NULL},
+ {0x001ec4, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec5, {[CaseLower] = 0x001ec5,[CaseTitle] = 0x001ec4,[CaseUpper] = 0x001ec4}, NULL},
+ {0x001ec6, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec7, {[CaseLower] = 0x001ec7,[CaseTitle] = 0x001ec6,[CaseUpper] = 0x001ec6}, NULL},
+ {0x001ec8, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001ec9, {[CaseLower] = 0x001ec9,[CaseTitle] = 0x001ec8,[CaseUpper] = 0x001ec8}, NULL},
+ {0x001eca, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecb, {[CaseLower] = 0x001ecb,[CaseTitle] = 0x001eca,[CaseUpper] = 0x001eca}, NULL},
+ {0x001ecc, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ecd, {[CaseLower] = 0x001ecd,[CaseTitle] = 0x001ecc,[CaseUpper] = 0x001ecc}, NULL},
+ {0x001ece, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ecf, {[CaseLower] = 0x001ecf,[CaseTitle] = 0x001ece,[CaseUpper] = 0x001ece}, NULL},
+ {0x001ed0, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed1, {[CaseLower] = 0x001ed1,[CaseTitle] = 0x001ed0,[CaseUpper] = 0x001ed0}, NULL},
+ {0x001ed2, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed3, {[CaseLower] = 0x001ed3,[CaseTitle] = 0x001ed2,[CaseUpper] = 0x001ed2}, NULL},
+ {0x001ed4, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed5, {[CaseLower] = 0x001ed5,[CaseTitle] = 0x001ed4,[CaseUpper] = 0x001ed4}, NULL},
+ {0x001ed6, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed7, {[CaseLower] = 0x001ed7,[CaseTitle] = 0x001ed6,[CaseUpper] = 0x001ed6}, NULL},
+ {0x001ed8, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001ed9, {[CaseLower] = 0x001ed9,[CaseTitle] = 0x001ed8,[CaseUpper] = 0x001ed8}, NULL},
+ {0x001eda, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edb, {[CaseLower] = 0x001edb,[CaseTitle] = 0x001eda,[CaseUpper] = 0x001eda}, NULL},
+ {0x001edc, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001edd, {[CaseLower] = 0x001edd,[CaseTitle] = 0x001edc,[CaseUpper] = 0x001edc}, NULL},
+ {0x001ede, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001edf, {[CaseLower] = 0x001edf,[CaseTitle] = 0x001ede,[CaseUpper] = 0x001ede}, NULL},
+ {0x001ee0, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee1, {[CaseLower] = 0x001ee1,[CaseTitle] = 0x001ee0,[CaseUpper] = 0x001ee0}, NULL},
+ {0x001ee2, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee3, {[CaseLower] = 0x001ee3,[CaseTitle] = 0x001ee2,[CaseUpper] = 0x001ee2}, NULL},
+ {0x001ee4, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee5, {[CaseLower] = 0x001ee5,[CaseTitle] = 0x001ee4,[CaseUpper] = 0x001ee4}, NULL},
+ {0x001ee6, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee7, {[CaseLower] = 0x001ee7,[CaseTitle] = 0x001ee6,[CaseUpper] = 0x001ee6}, NULL},
+ {0x001ee8, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001ee9, {[CaseLower] = 0x001ee9,[CaseTitle] = 0x001ee8,[CaseUpper] = 0x001ee8}, NULL},
+ {0x001eea, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eeb, {[CaseLower] = 0x001eeb,[CaseTitle] = 0x001eea,[CaseUpper] = 0x001eea}, NULL},
+ {0x001eec, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eed, {[CaseLower] = 0x001eed,[CaseTitle] = 0x001eec,[CaseUpper] = 0x001eec}, NULL},
+ {0x001eee, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001eef, {[CaseLower] = 0x001eef,[CaseTitle] = 0x001eee,[CaseUpper] = 0x001eee}, NULL},
+ {0x001ef0, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef1, {[CaseLower] = 0x001ef1,[CaseTitle] = 0x001ef0,[CaseUpper] = 0x001ef0}, NULL},
+ {0x001ef2, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef3, {[CaseLower] = 0x001ef3,[CaseTitle] = 0x001ef2,[CaseUpper] = 0x001ef2}, NULL},
+ {0x001ef4, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef5, {[CaseLower] = 0x001ef5,[CaseTitle] = 0x001ef4,[CaseUpper] = 0x001ef4}, NULL},
+ {0x001ef6, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef7, {[CaseLower] = 0x001ef7,[CaseTitle] = 0x001ef6,[CaseUpper] = 0x001ef6}, NULL},
+ {0x001ef8, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001ef9, {[CaseLower] = 0x001ef9,[CaseTitle] = 0x001ef8,[CaseUpper] = 0x001ef8}, NULL},
+ {0x001efa, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efb, {[CaseLower] = 0x001efb,[CaseTitle] = 0x001efa,[CaseUpper] = 0x001efa}, NULL},
+ {0x001efc, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efd, {[CaseLower] = 0x001efd,[CaseTitle] = 0x001efc,[CaseUpper] = 0x001efc}, NULL},
+ {0x001efe, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001eff, {[CaseLower] = 0x001eff,[CaseTitle] = 0x001efe,[CaseUpper] = 0x001efe}, NULL},
+ {0x001f00, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f01, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f02, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f03, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f04, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f05, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f06, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f07, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f08, {[CaseLower] = 0x001f00,[CaseTitle] = 0x001f08,[CaseUpper] = 0x001f08}, NULL},
+ {0x001f09, {[CaseLower] = 0x001f01,[CaseTitle] = 0x001f09,[CaseUpper] = 0x001f09}, NULL},
+ {0x001f0a, {[CaseLower] = 0x001f02,[CaseTitle] = 0x001f0a,[CaseUpper] = 0x001f0a}, NULL},
+ {0x001f0b, {[CaseLower] = 0x001f03,[CaseTitle] = 0x001f0b,[CaseUpper] = 0x001f0b}, NULL},
+ {0x001f0c, {[CaseLower] = 0x001f04,[CaseTitle] = 0x001f0c,[CaseUpper] = 0x001f0c}, NULL},
+ {0x001f0d, {[CaseLower] = 0x001f05,[CaseTitle] = 0x001f0d,[CaseUpper] = 0x001f0d}, NULL},
+ {0x001f0e, {[CaseLower] = 0x001f06,[CaseTitle] = 0x001f0e,[CaseUpper] = 0x001f0e}, NULL},
+ {0x001f0f, {[CaseLower] = 0x001f07,[CaseTitle] = 0x001f0f,[CaseUpper] = 0x001f0f}, NULL},
+ {0x001f10, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f11, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f12, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f13, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f14, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f15, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f18, {[CaseLower] = 0x001f10,[CaseTitle] = 0x001f18,[CaseUpper] = 0x001f18}, NULL},
+ {0x001f19, {[CaseLower] = 0x001f11,[CaseTitle] = 0x001f19,[CaseUpper] = 0x001f19}, NULL},
+ {0x001f1a, {[CaseLower] = 0x001f12,[CaseTitle] = 0x001f1a,[CaseUpper] = 0x001f1a}, NULL},
+ {0x001f1b, {[CaseLower] = 0x001f13,[CaseTitle] = 0x001f1b,[CaseUpper] = 0x001f1b}, NULL},
+ {0x001f1c, {[CaseLower] = 0x001f14,[CaseTitle] = 0x001f1c,[CaseUpper] = 0x001f1c}, NULL},
+ {0x001f1d, {[CaseLower] = 0x001f15,[CaseTitle] = 0x001f1d,[CaseUpper] = 0x001f1d}, NULL},
+ {0x001f20, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f21, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f22, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f23, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f24, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f25, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f26, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f27, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f28, {[CaseLower] = 0x001f20,[CaseTitle] = 0x001f28,[CaseUpper] = 0x001f28}, NULL},
+ {0x001f29, {[CaseLower] = 0x001f21,[CaseTitle] = 0x001f29,[CaseUpper] = 0x001f29}, NULL},
+ {0x001f2a, {[CaseLower] = 0x001f22,[CaseTitle] = 0x001f2a,[CaseUpper] = 0x001f2a}, NULL},
+ {0x001f2b, {[CaseLower] = 0x001f23,[CaseTitle] = 0x001f2b,[CaseUpper] = 0x001f2b}, NULL},
+ {0x001f2c, {[CaseLower] = 0x001f24,[CaseTitle] = 0x001f2c,[CaseUpper] = 0x001f2c}, NULL},
+ {0x001f2d, {[CaseLower] = 0x001f25,[CaseTitle] = 0x001f2d,[CaseUpper] = 0x001f2d}, NULL},
+ {0x001f2e, {[CaseLower] = 0x001f26,[CaseTitle] = 0x001f2e,[CaseUpper] = 0x001f2e}, NULL},
+ {0x001f2f, {[CaseLower] = 0x001f27,[CaseTitle] = 0x001f2f,[CaseUpper] = 0x001f2f}, NULL},
+ {0x001f30, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f31, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f32, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f33, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f34, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f35, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f36, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f37, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f38, {[CaseLower] = 0x001f30,[CaseTitle] = 0x001f38,[CaseUpper] = 0x001f38}, NULL},
+ {0x001f39, {[CaseLower] = 0x001f31,[CaseTitle] = 0x001f39,[CaseUpper] = 0x001f39}, NULL},
+ {0x001f3a, {[CaseLower] = 0x001f32,[CaseTitle] = 0x001f3a,[CaseUpper] = 0x001f3a}, NULL},
+ {0x001f3b, {[CaseLower] = 0x001f33,[CaseTitle] = 0x001f3b,[CaseUpper] = 0x001f3b}, NULL},
+ {0x001f3c, {[CaseLower] = 0x001f34,[CaseTitle] = 0x001f3c,[CaseUpper] = 0x001f3c}, NULL},
+ {0x001f3d, {[CaseLower] = 0x001f35,[CaseTitle] = 0x001f3d,[CaseUpper] = 0x001f3d}, NULL},
+ {0x001f3e, {[CaseLower] = 0x001f36,[CaseTitle] = 0x001f3e,[CaseUpper] = 0x001f3e}, NULL},
+ {0x001f3f, {[CaseLower] = 0x001f37,[CaseTitle] = 0x001f3f,[CaseUpper] = 0x001f3f}, NULL},
+ {0x001f40, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f41, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f42, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f43, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f44, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f45, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f48, {[CaseLower] = 0x001f40,[CaseTitle] = 0x001f48,[CaseUpper] = 0x001f48}, NULL},
+ {0x001f49, {[CaseLower] = 0x001f41,[CaseTitle] = 0x001f49,[CaseUpper] = 0x001f49}, NULL},
+ {0x001f4a, {[CaseLower] = 0x001f42,[CaseTitle] = 0x001f4a,[CaseUpper] = 0x001f4a}, NULL},
+ {0x001f4b, {[CaseLower] = 0x001f43,[CaseTitle] = 0x001f4b,[CaseUpper] = 0x001f4b}, NULL},
+ {0x001f4c, {[CaseLower] = 0x001f44,[CaseTitle] = 0x001f4c,[CaseUpper] = 0x001f4c}, NULL},
+ {0x001f4d, {[CaseLower] = 0x001f45,[CaseTitle] = 0x001f4d,[CaseUpper] = 0x001f4d}, NULL},
+ {0x001f50, {[CaseLower] = 0x001f50,[CaseTitle] = 0x001f50,[CaseUpper] = 0x001f50}, &special_case[13]},
+ {0x001f51, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f52, {[CaseLower] = 0x001f52,[CaseTitle] = 0x001f52,[CaseUpper] = 0x001f52}, &special_case[14]},
+ {0x001f53, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f54, {[CaseLower] = 0x001f54,[CaseTitle] = 0x001f54,[CaseUpper] = 0x001f54}, &special_case[15]},
+ {0x001f55, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f56, {[CaseLower] = 0x001f56,[CaseTitle] = 0x001f56,[CaseUpper] = 0x001f56}, &special_case[16]},
+ {0x001f57, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f59, {[CaseLower] = 0x001f51,[CaseTitle] = 0x001f59,[CaseUpper] = 0x001f59}, NULL},
+ {0x001f5b, {[CaseLower] = 0x001f53,[CaseTitle] = 0x001f5b,[CaseUpper] = 0x001f5b}, NULL},
+ {0x001f5d, {[CaseLower] = 0x001f55,[CaseTitle] = 0x001f5d,[CaseUpper] = 0x001f5d}, NULL},
+ {0x001f5f, {[CaseLower] = 0x001f57,[CaseTitle] = 0x001f5f,[CaseUpper] = 0x001f5f}, NULL},
+ {0x001f60, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f61, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f62, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f63, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f64, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f65, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f66, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f67, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f68, {[CaseLower] = 0x001f60,[CaseTitle] = 0x001f68,[CaseUpper] = 0x001f68}, NULL},
+ {0x001f69, {[CaseLower] = 0x001f61,[CaseTitle] = 0x001f69,[CaseUpper] = 0x001f69}, NULL},
+ {0x001f6a, {[CaseLower] = 0x001f62,[CaseTitle] = 0x001f6a,[CaseUpper] = 0x001f6a}, NULL},
+ {0x001f6b, {[CaseLower] = 0x001f63,[CaseTitle] = 0x001f6b,[CaseUpper] = 0x001f6b}, NULL},
+ {0x001f6c, {[CaseLower] = 0x001f64,[CaseTitle] = 0x001f6c,[CaseUpper] = 0x001f6c}, NULL},
+ {0x001f6d, {[CaseLower] = 0x001f65,[CaseTitle] = 0x001f6d,[CaseUpper] = 0x001f6d}, NULL},
+ {0x001f6e, {[CaseLower] = 0x001f66,[CaseTitle] = 0x001f6e,[CaseUpper] = 0x001f6e}, NULL},
+ {0x001f6f, {[CaseLower] = 0x001f67,[CaseTitle] = 0x001f6f,[CaseUpper] = 0x001f6f}, NULL},
+ {0x001f70, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001f71, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001f72, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001f73, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001f74, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001f75, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001f76, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001f77, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001f78, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001f79, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001f7a, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001f7b, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001f7c, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001f7d, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001f80, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[17]},
+ {0x001f81, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[18]},
+ {0x001f82, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[19]},
+ {0x001f83, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[20]},
+ {0x001f84, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[21]},
+ {0x001f85, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[22]},
+ {0x001f86, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[23]},
+ {0x001f87, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[24]},
+ {0x001f88, {[CaseLower] = 0x001f80,[CaseTitle] = 0x001f88,[CaseUpper] = 0x001f88}, &special_case[25]},
+ {0x001f89, {[CaseLower] = 0x001f81,[CaseTitle] = 0x001f89,[CaseUpper] = 0x001f89}, &special_case[26]},
+ {0x001f8a, {[CaseLower] = 0x001f82,[CaseTitle] = 0x001f8a,[CaseUpper] = 0x001f8a}, &special_case[27]},
+ {0x001f8b, {[CaseLower] = 0x001f83,[CaseTitle] = 0x001f8b,[CaseUpper] = 0x001f8b}, &special_case[28]},
+ {0x001f8c, {[CaseLower] = 0x001f84,[CaseTitle] = 0x001f8c,[CaseUpper] = 0x001f8c}, &special_case[29]},
+ {0x001f8d, {[CaseLower] = 0x001f85,[CaseTitle] = 0x001f8d,[CaseUpper] = 0x001f8d}, &special_case[30]},
+ {0x001f8e, {[CaseLower] = 0x001f86,[CaseTitle] = 0x001f8e,[CaseUpper] = 0x001f8e}, &special_case[31]},
+ {0x001f8f, {[CaseLower] = 0x001f87,[CaseTitle] = 0x001f8f,[CaseUpper] = 0x001f8f}, &special_case[32]},
+ {0x001f90, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[33]},
+ {0x001f91, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[34]},
+ {0x001f92, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[35]},
+ {0x001f93, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[36]},
+ {0x001f94, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[37]},
+ {0x001f95, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[38]},
+ {0x001f96, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[39]},
+ {0x001f97, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[40]},
+ {0x001f98, {[CaseLower] = 0x001f90,[CaseTitle] = 0x001f98,[CaseUpper] = 0x001f98}, &special_case[41]},
+ {0x001f99, {[CaseLower] = 0x001f91,[CaseTitle] = 0x001f99,[CaseUpper] = 0x001f99}, &special_case[42]},
+ {0x001f9a, {[CaseLower] = 0x001f92,[CaseTitle] = 0x001f9a,[CaseUpper] = 0x001f9a}, &special_case[43]},
+ {0x001f9b, {[CaseLower] = 0x001f93,[CaseTitle] = 0x001f9b,[CaseUpper] = 0x001f9b}, &special_case[44]},
+ {0x001f9c, {[CaseLower] = 0x001f94,[CaseTitle] = 0x001f9c,[CaseUpper] = 0x001f9c}, &special_case[45]},
+ {0x001f9d, {[CaseLower] = 0x001f95,[CaseTitle] = 0x001f9d,[CaseUpper] = 0x001f9d}, &special_case[46]},
+ {0x001f9e, {[CaseLower] = 0x001f96,[CaseTitle] = 0x001f9e,[CaseUpper] = 0x001f9e}, &special_case[47]},
+ {0x001f9f, {[CaseLower] = 0x001f97,[CaseTitle] = 0x001f9f,[CaseUpper] = 0x001f9f}, &special_case[48]},
+ {0x001fa0, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[49]},
+ {0x001fa1, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[50]},
+ {0x001fa2, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[51]},
+ {0x001fa3, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[52]},
+ {0x001fa4, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[53]},
+ {0x001fa5, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[54]},
+ {0x001fa6, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[55]},
+ {0x001fa7, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[56]},
+ {0x001fa8, {[CaseLower] = 0x001fa0,[CaseTitle] = 0x001fa8,[CaseUpper] = 0x001fa8}, &special_case[57]},
+ {0x001fa9, {[CaseLower] = 0x001fa1,[CaseTitle] = 0x001fa9,[CaseUpper] = 0x001fa9}, &special_case[58]},
+ {0x001faa, {[CaseLower] = 0x001fa2,[CaseTitle] = 0x001faa,[CaseUpper] = 0x001faa}, &special_case[59]},
+ {0x001fab, {[CaseLower] = 0x001fa3,[CaseTitle] = 0x001fab,[CaseUpper] = 0x001fab}, &special_case[60]},
+ {0x001fac, {[CaseLower] = 0x001fa4,[CaseTitle] = 0x001fac,[CaseUpper] = 0x001fac}, &special_case[61]},
+ {0x001fad, {[CaseLower] = 0x001fa5,[CaseTitle] = 0x001fad,[CaseUpper] = 0x001fad}, &special_case[62]},
+ {0x001fae, {[CaseLower] = 0x001fa6,[CaseTitle] = 0x001fae,[CaseUpper] = 0x001fae}, &special_case[63]},
+ {0x001faf, {[CaseLower] = 0x001fa7,[CaseTitle] = 0x001faf,[CaseUpper] = 0x001faf}, &special_case[64]},
+ {0x001fb0, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb1, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fb2, {[CaseLower] = 0x001fb2,[CaseTitle] = 0x001fb2,[CaseUpper] = 0x001fb2}, &special_case[65]},
+ {0x001fb3, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[66]},
+ {0x001fb4, {[CaseLower] = 0x001fb4,[CaseTitle] = 0x001fb4,[CaseUpper] = 0x001fb4}, &special_case[67]},
+ {0x001fb6, {[CaseLower] = 0x001fb6,[CaseTitle] = 0x001fb6,[CaseUpper] = 0x001fb6}, &special_case[68]},
+ {0x001fb7, {[CaseLower] = 0x001fb7,[CaseTitle] = 0x001fb7,[CaseUpper] = 0x001fb7}, &special_case[69]},
+ {0x001fb8, {[CaseLower] = 0x001fb0,[CaseTitle] = 0x001fb8,[CaseUpper] = 0x001fb8}, NULL},
+ {0x001fb9, {[CaseLower] = 0x001fb1,[CaseTitle] = 0x001fb9,[CaseUpper] = 0x001fb9}, NULL},
+ {0x001fba, {[CaseLower] = 0x001f70,[CaseTitle] = 0x001fba,[CaseUpper] = 0x001fba}, NULL},
+ {0x001fbb, {[CaseLower] = 0x001f71,[CaseTitle] = 0x001fbb,[CaseUpper] = 0x001fbb}, NULL},
+ {0x001fbc, {[CaseLower] = 0x001fb3,[CaseTitle] = 0x001fbc,[CaseUpper] = 0x001fbc}, &special_case[70]},
+ {0x001fbe, {[CaseLower] = 0x001fbe,[CaseTitle] = 0x000399,[CaseUpper] = 0x000399}, NULL},
+ {0x001fc2, {[CaseLower] = 0x001fc2,[CaseTitle] = 0x001fc2,[CaseUpper] = 0x001fc2}, &special_case[71]},
+ {0x001fc3, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[72]},
+ {0x001fc4, {[CaseLower] = 0x001fc4,[CaseTitle] = 0x001fc4,[CaseUpper] = 0x001fc4}, &special_case[73]},
+ {0x001fc6, {[CaseLower] = 0x001fc6,[CaseTitle] = 0x001fc6,[CaseUpper] = 0x001fc6}, &special_case[74]},
+ {0x001fc7, {[CaseLower] = 0x001fc7,[CaseTitle] = 0x001fc7,[CaseUpper] = 0x001fc7}, &special_case[75]},
+ {0x001fc8, {[CaseLower] = 0x001f72,[CaseTitle] = 0x001fc8,[CaseUpper] = 0x001fc8}, NULL},
+ {0x001fc9, {[CaseLower] = 0x001f73,[CaseTitle] = 0x001fc9,[CaseUpper] = 0x001fc9}, NULL},
+ {0x001fca, {[CaseLower] = 0x001f74,[CaseTitle] = 0x001fca,[CaseUpper] = 0x001fca}, NULL},
+ {0x001fcb, {[CaseLower] = 0x001f75,[CaseTitle] = 0x001fcb,[CaseUpper] = 0x001fcb}, NULL},
+ {0x001fcc, {[CaseLower] = 0x001fc3,[CaseTitle] = 0x001fcc,[CaseUpper] = 0x001fcc}, &special_case[76]},
+ {0x001fd0, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd1, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fd2, {[CaseLower] = 0x001fd2,[CaseTitle] = 0x001fd2,[CaseUpper] = 0x001fd2}, &special_case[77]},
+ {0x001fd3, {[CaseLower] = 0x001fd3,[CaseTitle] = 0x001fd3,[CaseUpper] = 0x001fd3}, &special_case[78]},
+ {0x001fd6, {[CaseLower] = 0x001fd6,[CaseTitle] = 0x001fd6,[CaseUpper] = 0x001fd6}, &special_case[79]},
+ {0x001fd7, {[CaseLower] = 0x001fd7,[CaseTitle] = 0x001fd7,[CaseUpper] = 0x001fd7}, &special_case[80]},
+ {0x001fd8, {[CaseLower] = 0x001fd0,[CaseTitle] = 0x001fd8,[CaseUpper] = 0x001fd8}, NULL},
+ {0x001fd9, {[CaseLower] = 0x001fd1,[CaseTitle] = 0x001fd9,[CaseUpper] = 0x001fd9}, NULL},
+ {0x001fda, {[CaseLower] = 0x001f76,[CaseTitle] = 0x001fda,[CaseUpper] = 0x001fda}, NULL},
+ {0x001fdb, {[CaseLower] = 0x001f77,[CaseTitle] = 0x001fdb,[CaseUpper] = 0x001fdb}, NULL},
+ {0x001fe0, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe1, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fe2, {[CaseLower] = 0x001fe2,[CaseTitle] = 0x001fe2,[CaseUpper] = 0x001fe2}, &special_case[81]},
+ {0x001fe3, {[CaseLower] = 0x001fe3,[CaseTitle] = 0x001fe3,[CaseUpper] = 0x001fe3}, &special_case[82]},
+ {0x001fe4, {[CaseLower] = 0x001fe4,[CaseTitle] = 0x001fe4,[CaseUpper] = 0x001fe4}, &special_case[83]},
+ {0x001fe5, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001fe6, {[CaseLower] = 0x001fe6,[CaseTitle] = 0x001fe6,[CaseUpper] = 0x001fe6}, &special_case[84]},
+ {0x001fe7, {[CaseLower] = 0x001fe7,[CaseTitle] = 0x001fe7,[CaseUpper] = 0x001fe7}, &special_case[85]},
+ {0x001fe8, {[CaseLower] = 0x001fe0,[CaseTitle] = 0x001fe8,[CaseUpper] = 0x001fe8}, NULL},
+ {0x001fe9, {[CaseLower] = 0x001fe1,[CaseTitle] = 0x001fe9,[CaseUpper] = 0x001fe9}, NULL},
+ {0x001fea, {[CaseLower] = 0x001f7a,[CaseTitle] = 0x001fea,[CaseUpper] = 0x001fea}, NULL},
+ {0x001feb, {[CaseLower] = 0x001f7b,[CaseTitle] = 0x001feb,[CaseUpper] = 0x001feb}, NULL},
+ {0x001fec, {[CaseLower] = 0x001fe5,[CaseTitle] = 0x001fec,[CaseUpper] = 0x001fec}, NULL},
+ {0x001ff2, {[CaseLower] = 0x001ff2,[CaseTitle] = 0x001ff2,[CaseUpper] = 0x001ff2}, &special_case[86]},
+ {0x001ff3, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[87]},
+ {0x001ff4, {[CaseLower] = 0x001ff4,[CaseTitle] = 0x001ff4,[CaseUpper] = 0x001ff4}, &special_case[88]},
+ {0x001ff6, {[CaseLower] = 0x001ff6,[CaseTitle] = 0x001ff6,[CaseUpper] = 0x001ff6}, &special_case[89]},
+ {0x001ff7, {[CaseLower] = 0x001ff7,[CaseTitle] = 0x001ff7,[CaseUpper] = 0x001ff7}, &special_case[90]},
+ {0x001ff8, {[CaseLower] = 0x001f78,[CaseTitle] = 0x001ff8,[CaseUpper] = 0x001ff8}, NULL},
+ {0x001ff9, {[CaseLower] = 0x001f79,[CaseTitle] = 0x001ff9,[CaseUpper] = 0x001ff9}, NULL},
+ {0x001ffa, {[CaseLower] = 0x001f7c,[CaseTitle] = 0x001ffa,[CaseUpper] = 0x001ffa}, NULL},
+ {0x001ffb, {[CaseLower] = 0x001f7d,[CaseTitle] = 0x001ffb,[CaseUpper] = 0x001ffb}, NULL},
+ {0x001ffc, {[CaseLower] = 0x001ff3,[CaseTitle] = 0x001ffc,[CaseUpper] = 0x001ffc}, &special_case[91]},
+ {0x002126, {[CaseLower] = 0x0003c9,[CaseTitle] = 0x002126,[CaseUpper] = 0x002126}, NULL},
+ {0x00212a, {[CaseLower] = 0x00006b,[CaseTitle] = 0x00212a,[CaseUpper] = 0x00212a}, NULL},
+ {0x00212b, {[CaseLower] = 0x0000e5,[CaseTitle] = 0x00212b,[CaseUpper] = 0x00212b}, NULL},
+ {0x002132, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x00214e, {[CaseLower] = 0x00214e,[CaseTitle] = 0x002132,[CaseUpper] = 0x002132}, NULL},
+ {0x002160, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002161, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002162, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002163, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002164, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002165, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002166, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002167, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002168, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002169, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00216a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00216b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00216c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00216d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00216e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00216f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002170, {[CaseLower] = 0x002170,[CaseTitle] = 0x002160,[CaseUpper] = 0x002160}, NULL},
+ {0x002171, {[CaseLower] = 0x002171,[CaseTitle] = 0x002161,[CaseUpper] = 0x002161}, NULL},
+ {0x002172, {[CaseLower] = 0x002172,[CaseTitle] = 0x002162,[CaseUpper] = 0x002162}, NULL},
+ {0x002173, {[CaseLower] = 0x002173,[CaseTitle] = 0x002163,[CaseUpper] = 0x002163}, NULL},
+ {0x002174, {[CaseLower] = 0x002174,[CaseTitle] = 0x002164,[CaseUpper] = 0x002164}, NULL},
+ {0x002175, {[CaseLower] = 0x002175,[CaseTitle] = 0x002165,[CaseUpper] = 0x002165}, NULL},
+ {0x002176, {[CaseLower] = 0x002176,[CaseTitle] = 0x002166,[CaseUpper] = 0x002166}, NULL},
+ {0x002177, {[CaseLower] = 0x002177,[CaseTitle] = 0x002167,[CaseUpper] = 0x002167}, NULL},
+ {0x002178, {[CaseLower] = 0x002178,[CaseTitle] = 0x002168,[CaseUpper] = 0x002168}, NULL},
+ {0x002179, {[CaseLower] = 0x002179,[CaseTitle] = 0x002169,[CaseUpper] = 0x002169}, NULL},
+ {0x00217a, {[CaseLower] = 0x00217a,[CaseTitle] = 0x00216a,[CaseUpper] = 0x00216a}, NULL},
+ {0x00217b, {[CaseLower] = 0x00217b,[CaseTitle] = 0x00216b,[CaseUpper] = 0x00216b}, NULL},
+ {0x00217c, {[CaseLower] = 0x00217c,[CaseTitle] = 0x00216c,[CaseUpper] = 0x00216c}, NULL},
+ {0x00217d, {[CaseLower] = 0x00217d,[CaseTitle] = 0x00216d,[CaseUpper] = 0x00216d}, NULL},
+ {0x00217e, {[CaseLower] = 0x00217e,[CaseTitle] = 0x00216e,[CaseUpper] = 0x00216e}, NULL},
+ {0x00217f, {[CaseLower] = 0x00217f,[CaseTitle] = 0x00216f,[CaseUpper] = 0x00216f}, NULL},
+ {0x002183, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x002184, {[CaseLower] = 0x002184,[CaseTitle] = 0x002183,[CaseUpper] = 0x002183}, NULL},
+ {0x0024b6, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024b7, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024b8, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024b9, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024ba, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024bb, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024bc, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024bd, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024be, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024bf, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024c0, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024c1, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024c2, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024c3, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024c4, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024c5, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024c6, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024c7, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024c8, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024c9, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024ca, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024cb, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024cc, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024cd, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024ce, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024cf, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x0024d0, {[CaseLower] = 0x0024d0,[CaseTitle] = 0x0024b6,[CaseUpper] = 0x0024b6}, NULL},
+ {0x0024d1, {[CaseLower] = 0x0024d1,[CaseTitle] = 0x0024b7,[CaseUpper] = 0x0024b7}, NULL},
+ {0x0024d2, {[CaseLower] = 0x0024d2,[CaseTitle] = 0x0024b8,[CaseUpper] = 0x0024b8}, NULL},
+ {0x0024d3, {[CaseLower] = 0x0024d3,[CaseTitle] = 0x0024b9,[CaseUpper] = 0x0024b9}, NULL},
+ {0x0024d4, {[CaseLower] = 0x0024d4,[CaseTitle] = 0x0024ba,[CaseUpper] = 0x0024ba}, NULL},
+ {0x0024d5, {[CaseLower] = 0x0024d5,[CaseTitle] = 0x0024bb,[CaseUpper] = 0x0024bb}, NULL},
+ {0x0024d6, {[CaseLower] = 0x0024d6,[CaseTitle] = 0x0024bc,[CaseUpper] = 0x0024bc}, NULL},
+ {0x0024d7, {[CaseLower] = 0x0024d7,[CaseTitle] = 0x0024bd,[CaseUpper] = 0x0024bd}, NULL},
+ {0x0024d8, {[CaseLower] = 0x0024d8,[CaseTitle] = 0x0024be,[CaseUpper] = 0x0024be}, NULL},
+ {0x0024d9, {[CaseLower] = 0x0024d9,[CaseTitle] = 0x0024bf,[CaseUpper] = 0x0024bf}, NULL},
+ {0x0024da, {[CaseLower] = 0x0024da,[CaseTitle] = 0x0024c0,[CaseUpper] = 0x0024c0}, NULL},
+ {0x0024db, {[CaseLower] = 0x0024db,[CaseTitle] = 0x0024c1,[CaseUpper] = 0x0024c1}, NULL},
+ {0x0024dc, {[CaseLower] = 0x0024dc,[CaseTitle] = 0x0024c2,[CaseUpper] = 0x0024c2}, NULL},
+ {0x0024dd, {[CaseLower] = 0x0024dd,[CaseTitle] = 0x0024c3,[CaseUpper] = 0x0024c3}, NULL},
+ {0x0024de, {[CaseLower] = 0x0024de,[CaseTitle] = 0x0024c4,[CaseUpper] = 0x0024c4}, NULL},
+ {0x0024df, {[CaseLower] = 0x0024df,[CaseTitle] = 0x0024c5,[CaseUpper] = 0x0024c5}, NULL},
+ {0x0024e0, {[CaseLower] = 0x0024e0,[CaseTitle] = 0x0024c6,[CaseUpper] = 0x0024c6}, NULL},
+ {0x0024e1, {[CaseLower] = 0x0024e1,[CaseTitle] = 0x0024c7,[CaseUpper] = 0x0024c7}, NULL},
+ {0x0024e2, {[CaseLower] = 0x0024e2,[CaseTitle] = 0x0024c8,[CaseUpper] = 0x0024c8}, NULL},
+ {0x0024e3, {[CaseLower] = 0x0024e3,[CaseTitle] = 0x0024c9,[CaseUpper] = 0x0024c9}, NULL},
+ {0x0024e4, {[CaseLower] = 0x0024e4,[CaseTitle] = 0x0024ca,[CaseUpper] = 0x0024ca}, NULL},
+ {0x0024e5, {[CaseLower] = 0x0024e5,[CaseTitle] = 0x0024cb,[CaseUpper] = 0x0024cb}, NULL},
+ {0x0024e6, {[CaseLower] = 0x0024e6,[CaseTitle] = 0x0024cc,[CaseUpper] = 0x0024cc}, NULL},
+ {0x0024e7, {[CaseLower] = 0x0024e7,[CaseTitle] = 0x0024cd,[CaseUpper] = 0x0024cd}, NULL},
+ {0x0024e8, {[CaseLower] = 0x0024e8,[CaseTitle] = 0x0024ce,[CaseUpper] = 0x0024ce}, NULL},
+ {0x0024e9, {[CaseLower] = 0x0024e9,[CaseTitle] = 0x0024cf,[CaseUpper] = 0x0024cf}, NULL},
+ {0x002c00, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c01, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c02, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c03, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c04, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c05, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c06, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c07, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c08, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c09, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c0a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c0b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c0c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c0d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c0e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c0f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c10, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c11, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c12, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c13, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c14, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c15, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c16, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c17, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c18, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c19, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c1a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c1b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c1c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c1d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c1e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c1f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c20, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c21, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c22, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c23, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c24, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c25, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c26, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c27, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c28, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c29, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c2a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c2b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c2c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c2d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c2e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c2f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c30, {[CaseLower] = 0x002c30,[CaseTitle] = 0x002c00,[CaseUpper] = 0x002c00}, NULL},
+ {0x002c31, {[CaseLower] = 0x002c31,[CaseTitle] = 0x002c01,[CaseUpper] = 0x002c01}, NULL},
+ {0x002c32, {[CaseLower] = 0x002c32,[CaseTitle] = 0x002c02,[CaseUpper] = 0x002c02}, NULL},
+ {0x002c33, {[CaseLower] = 0x002c33,[CaseTitle] = 0x002c03,[CaseUpper] = 0x002c03}, NULL},
+ {0x002c34, {[CaseLower] = 0x002c34,[CaseTitle] = 0x002c04,[CaseUpper] = 0x002c04}, NULL},
+ {0x002c35, {[CaseLower] = 0x002c35,[CaseTitle] = 0x002c05,[CaseUpper] = 0x002c05}, NULL},
+ {0x002c36, {[CaseLower] = 0x002c36,[CaseTitle] = 0x002c06,[CaseUpper] = 0x002c06}, NULL},
+ {0x002c37, {[CaseLower] = 0x002c37,[CaseTitle] = 0x002c07,[CaseUpper] = 0x002c07}, NULL},
+ {0x002c38, {[CaseLower] = 0x002c38,[CaseTitle] = 0x002c08,[CaseUpper] = 0x002c08}, NULL},
+ {0x002c39, {[CaseLower] = 0x002c39,[CaseTitle] = 0x002c09,[CaseUpper] = 0x002c09}, NULL},
+ {0x002c3a, {[CaseLower] = 0x002c3a,[CaseTitle] = 0x002c0a,[CaseUpper] = 0x002c0a}, NULL},
+ {0x002c3b, {[CaseLower] = 0x002c3b,[CaseTitle] = 0x002c0b,[CaseUpper] = 0x002c0b}, NULL},
+ {0x002c3c, {[CaseLower] = 0x002c3c,[CaseTitle] = 0x002c0c,[CaseUpper] = 0x002c0c}, NULL},
+ {0x002c3d, {[CaseLower] = 0x002c3d,[CaseTitle] = 0x002c0d,[CaseUpper] = 0x002c0d}, NULL},
+ {0x002c3e, {[CaseLower] = 0x002c3e,[CaseTitle] = 0x002c0e,[CaseUpper] = 0x002c0e}, NULL},
+ {0x002c3f, {[CaseLower] = 0x002c3f,[CaseTitle] = 0x002c0f,[CaseUpper] = 0x002c0f}, NULL},
+ {0x002c40, {[CaseLower] = 0x002c40,[CaseTitle] = 0x002c10,[CaseUpper] = 0x002c10}, NULL},
+ {0x002c41, {[CaseLower] = 0x002c41,[CaseTitle] = 0x002c11,[CaseUpper] = 0x002c11}, NULL},
+ {0x002c42, {[CaseLower] = 0x002c42,[CaseTitle] = 0x002c12,[CaseUpper] = 0x002c12}, NULL},
+ {0x002c43, {[CaseLower] = 0x002c43,[CaseTitle] = 0x002c13,[CaseUpper] = 0x002c13}, NULL},
+ {0x002c44, {[CaseLower] = 0x002c44,[CaseTitle] = 0x002c14,[CaseUpper] = 0x002c14}, NULL},
+ {0x002c45, {[CaseLower] = 0x002c45,[CaseTitle] = 0x002c15,[CaseUpper] = 0x002c15}, NULL},
+ {0x002c46, {[CaseLower] = 0x002c46,[CaseTitle] = 0x002c16,[CaseUpper] = 0x002c16}, NULL},
+ {0x002c47, {[CaseLower] = 0x002c47,[CaseTitle] = 0x002c17,[CaseUpper] = 0x002c17}, NULL},
+ {0x002c48, {[CaseLower] = 0x002c48,[CaseTitle] = 0x002c18,[CaseUpper] = 0x002c18}, NULL},
+ {0x002c49, {[CaseLower] = 0x002c49,[CaseTitle] = 0x002c19,[CaseUpper] = 0x002c19}, NULL},
+ {0x002c4a, {[CaseLower] = 0x002c4a,[CaseTitle] = 0x002c1a,[CaseUpper] = 0x002c1a}, NULL},
+ {0x002c4b, {[CaseLower] = 0x002c4b,[CaseTitle] = 0x002c1b,[CaseUpper] = 0x002c1b}, NULL},
+ {0x002c4c, {[CaseLower] = 0x002c4c,[CaseTitle] = 0x002c1c,[CaseUpper] = 0x002c1c}, NULL},
+ {0x002c4d, {[CaseLower] = 0x002c4d,[CaseTitle] = 0x002c1d,[CaseUpper] = 0x002c1d}, NULL},
+ {0x002c4e, {[CaseLower] = 0x002c4e,[CaseTitle] = 0x002c1e,[CaseUpper] = 0x002c1e}, NULL},
+ {0x002c4f, {[CaseLower] = 0x002c4f,[CaseTitle] = 0x002c1f,[CaseUpper] = 0x002c1f}, NULL},
+ {0x002c50, {[CaseLower] = 0x002c50,[CaseTitle] = 0x002c20,[CaseUpper] = 0x002c20}, NULL},
+ {0x002c51, {[CaseLower] = 0x002c51,[CaseTitle] = 0x002c21,[CaseUpper] = 0x002c21}, NULL},
+ {0x002c52, {[CaseLower] = 0x002c52,[CaseTitle] = 0x002c22,[CaseUpper] = 0x002c22}, NULL},
+ {0x002c53, {[CaseLower] = 0x002c53,[CaseTitle] = 0x002c23,[CaseUpper] = 0x002c23}, NULL},
+ {0x002c54, {[CaseLower] = 0x002c54,[CaseTitle] = 0x002c24,[CaseUpper] = 0x002c24}, NULL},
+ {0x002c55, {[CaseLower] = 0x002c55,[CaseTitle] = 0x002c25,[CaseUpper] = 0x002c25}, NULL},
+ {0x002c56, {[CaseLower] = 0x002c56,[CaseTitle] = 0x002c26,[CaseUpper] = 0x002c26}, NULL},
+ {0x002c57, {[CaseLower] = 0x002c57,[CaseTitle] = 0x002c27,[CaseUpper] = 0x002c27}, NULL},
+ {0x002c58, {[CaseLower] = 0x002c58,[CaseTitle] = 0x002c28,[CaseUpper] = 0x002c28}, NULL},
+ {0x002c59, {[CaseLower] = 0x002c59,[CaseTitle] = 0x002c29,[CaseUpper] = 0x002c29}, NULL},
+ {0x002c5a, {[CaseLower] = 0x002c5a,[CaseTitle] = 0x002c2a,[CaseUpper] = 0x002c2a}, NULL},
+ {0x002c5b, {[CaseLower] = 0x002c5b,[CaseTitle] = 0x002c2b,[CaseUpper] = 0x002c2b}, NULL},
+ {0x002c5c, {[CaseLower] = 0x002c5c,[CaseTitle] = 0x002c2c,[CaseUpper] = 0x002c2c}, NULL},
+ {0x002c5d, {[CaseLower] = 0x002c5d,[CaseTitle] = 0x002c2d,[CaseUpper] = 0x002c2d}, NULL},
+ {0x002c5e, {[CaseLower] = 0x002c5e,[CaseTitle] = 0x002c2e,[CaseUpper] = 0x002c2e}, NULL},
+ {0x002c5f, {[CaseLower] = 0x002c5f,[CaseTitle] = 0x002c2f,[CaseUpper] = 0x002c2f}, NULL},
+ {0x002c60, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c61, {[CaseLower] = 0x002c61,[CaseTitle] = 0x002c60,[CaseUpper] = 0x002c60}, NULL},
+ {0x002c62, {[CaseLower] = 0x00026b,[CaseTitle] = 0x002c62,[CaseUpper] = 0x002c62}, NULL},
+ {0x002c63, {[CaseLower] = 0x001d7d,[CaseTitle] = 0x002c63,[CaseUpper] = 0x002c63}, NULL},
+ {0x002c64, {[CaseLower] = 0x00027d,[CaseTitle] = 0x002c64,[CaseUpper] = 0x002c64}, NULL},
+ {0x002c65, {[CaseLower] = 0x002c65,[CaseTitle] = 0x00023a,[CaseUpper] = 0x00023a}, NULL},
+ {0x002c66, {[CaseLower] = 0x002c66,[CaseTitle] = 0x00023e,[CaseUpper] = 0x00023e}, NULL},
+ {0x002c67, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c68, {[CaseLower] = 0x002c68,[CaseTitle] = 0x002c67,[CaseUpper] = 0x002c67}, NULL},
+ {0x002c69, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6a, {[CaseLower] = 0x002c6a,[CaseTitle] = 0x002c69,[CaseUpper] = 0x002c69}, NULL},
+ {0x002c6b, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6c, {[CaseLower] = 0x002c6c,[CaseTitle] = 0x002c6b,[CaseUpper] = 0x002c6b}, NULL},
+ {0x002c6d, {[CaseLower] = 0x000251,[CaseTitle] = 0x002c6d,[CaseUpper] = 0x002c6d}, NULL},
+ {0x002c6e, {[CaseLower] = 0x000271,[CaseTitle] = 0x002c6e,[CaseUpper] = 0x002c6e}, NULL},
+ {0x002c6f, {[CaseLower] = 0x000250,[CaseTitle] = 0x002c6f,[CaseUpper] = 0x002c6f}, NULL},
+ {0x002c70, {[CaseLower] = 0x000252,[CaseTitle] = 0x002c70,[CaseUpper] = 0x002c70}, NULL},
+ {0x002c72, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c73, {[CaseLower] = 0x002c73,[CaseTitle] = 0x002c72,[CaseUpper] = 0x002c72}, NULL},
+ {0x002c75, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c76, {[CaseLower] = 0x002c76,[CaseTitle] = 0x002c75,[CaseUpper] = 0x002c75}, NULL},
+ {0x002c7e, {[CaseLower] = 0x00023f,[CaseTitle] = 0x002c7e,[CaseUpper] = 0x002c7e}, NULL},
+ {0x002c7f, {[CaseLower] = 0x000240,[CaseTitle] = 0x002c7f,[CaseUpper] = 0x002c7f}, NULL},
+ {0x002c80, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c81, {[CaseLower] = 0x002c81,[CaseTitle] = 0x002c80,[CaseUpper] = 0x002c80}, NULL},
+ {0x002c82, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c83, {[CaseLower] = 0x002c83,[CaseTitle] = 0x002c82,[CaseUpper] = 0x002c82}, NULL},
+ {0x002c84, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c85, {[CaseLower] = 0x002c85,[CaseTitle] = 0x002c84,[CaseUpper] = 0x002c84}, NULL},
+ {0x002c86, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c87, {[CaseLower] = 0x002c87,[CaseTitle] = 0x002c86,[CaseUpper] = 0x002c86}, NULL},
+ {0x002c88, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c89, {[CaseLower] = 0x002c89,[CaseTitle] = 0x002c88,[CaseUpper] = 0x002c88}, NULL},
+ {0x002c8a, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8b, {[CaseLower] = 0x002c8b,[CaseTitle] = 0x002c8a,[CaseUpper] = 0x002c8a}, NULL},
+ {0x002c8c, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8d, {[CaseLower] = 0x002c8d,[CaseTitle] = 0x002c8c,[CaseUpper] = 0x002c8c}, NULL},
+ {0x002c8e, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c8f, {[CaseLower] = 0x002c8f,[CaseTitle] = 0x002c8e,[CaseUpper] = 0x002c8e}, NULL},
+ {0x002c90, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c91, {[CaseLower] = 0x002c91,[CaseTitle] = 0x002c90,[CaseUpper] = 0x002c90}, NULL},
+ {0x002c92, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c93, {[CaseLower] = 0x002c93,[CaseTitle] = 0x002c92,[CaseUpper] = 0x002c92}, NULL},
+ {0x002c94, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c95, {[CaseLower] = 0x002c95,[CaseTitle] = 0x002c94,[CaseUpper] = 0x002c94}, NULL},
+ {0x002c96, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c97, {[CaseLower] = 0x002c97,[CaseTitle] = 0x002c96,[CaseUpper] = 0x002c96}, NULL},
+ {0x002c98, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c99, {[CaseLower] = 0x002c99,[CaseTitle] = 0x002c98,[CaseUpper] = 0x002c98}, NULL},
+ {0x002c9a, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9b, {[CaseLower] = 0x002c9b,[CaseTitle] = 0x002c9a,[CaseUpper] = 0x002c9a}, NULL},
+ {0x002c9c, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9d, {[CaseLower] = 0x002c9d,[CaseTitle] = 0x002c9c,[CaseUpper] = 0x002c9c}, NULL},
+ {0x002c9e, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002c9f, {[CaseLower] = 0x002c9f,[CaseTitle] = 0x002c9e,[CaseUpper] = 0x002c9e}, NULL},
+ {0x002ca0, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca1, {[CaseLower] = 0x002ca1,[CaseTitle] = 0x002ca0,[CaseUpper] = 0x002ca0}, NULL},
+ {0x002ca2, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca3, {[CaseLower] = 0x002ca3,[CaseTitle] = 0x002ca2,[CaseUpper] = 0x002ca2}, NULL},
+ {0x002ca4, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca5, {[CaseLower] = 0x002ca5,[CaseTitle] = 0x002ca4,[CaseUpper] = 0x002ca4}, NULL},
+ {0x002ca6, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca7, {[CaseLower] = 0x002ca7,[CaseTitle] = 0x002ca6,[CaseUpper] = 0x002ca6}, NULL},
+ {0x002ca8, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002ca9, {[CaseLower] = 0x002ca9,[CaseTitle] = 0x002ca8,[CaseUpper] = 0x002ca8}, NULL},
+ {0x002caa, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cab, {[CaseLower] = 0x002cab,[CaseTitle] = 0x002caa,[CaseUpper] = 0x002caa}, NULL},
+ {0x002cac, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cad, {[CaseLower] = 0x002cad,[CaseTitle] = 0x002cac,[CaseUpper] = 0x002cac}, NULL},
+ {0x002cae, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002caf, {[CaseLower] = 0x002caf,[CaseTitle] = 0x002cae,[CaseUpper] = 0x002cae}, NULL},
+ {0x002cb0, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb1, {[CaseLower] = 0x002cb1,[CaseTitle] = 0x002cb0,[CaseUpper] = 0x002cb0}, NULL},
+ {0x002cb2, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb3, {[CaseLower] = 0x002cb3,[CaseTitle] = 0x002cb2,[CaseUpper] = 0x002cb2}, NULL},
+ {0x002cb4, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb5, {[CaseLower] = 0x002cb5,[CaseTitle] = 0x002cb4,[CaseUpper] = 0x002cb4}, NULL},
+ {0x002cb6, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb7, {[CaseLower] = 0x002cb7,[CaseTitle] = 0x002cb6,[CaseUpper] = 0x002cb6}, NULL},
+ {0x002cb8, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cb9, {[CaseLower] = 0x002cb9,[CaseTitle] = 0x002cb8,[CaseUpper] = 0x002cb8}, NULL},
+ {0x002cba, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbb, {[CaseLower] = 0x002cbb,[CaseTitle] = 0x002cba,[CaseUpper] = 0x002cba}, NULL},
+ {0x002cbc, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbd, {[CaseLower] = 0x002cbd,[CaseTitle] = 0x002cbc,[CaseUpper] = 0x002cbc}, NULL},
+ {0x002cbe, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cbf, {[CaseLower] = 0x002cbf,[CaseTitle] = 0x002cbe,[CaseUpper] = 0x002cbe}, NULL},
+ {0x002cc0, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc1, {[CaseLower] = 0x002cc1,[CaseTitle] = 0x002cc0,[CaseUpper] = 0x002cc0}, NULL},
+ {0x002cc2, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc3, {[CaseLower] = 0x002cc3,[CaseTitle] = 0x002cc2,[CaseUpper] = 0x002cc2}, NULL},
+ {0x002cc4, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc5, {[CaseLower] = 0x002cc5,[CaseTitle] = 0x002cc4,[CaseUpper] = 0x002cc4}, NULL},
+ {0x002cc6, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc7, {[CaseLower] = 0x002cc7,[CaseTitle] = 0x002cc6,[CaseUpper] = 0x002cc6}, NULL},
+ {0x002cc8, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cc9, {[CaseLower] = 0x002cc9,[CaseTitle] = 0x002cc8,[CaseUpper] = 0x002cc8}, NULL},
+ {0x002cca, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccb, {[CaseLower] = 0x002ccb,[CaseTitle] = 0x002cca,[CaseUpper] = 0x002cca}, NULL},
+ {0x002ccc, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002ccd, {[CaseLower] = 0x002ccd,[CaseTitle] = 0x002ccc,[CaseUpper] = 0x002ccc}, NULL},
+ {0x002cce, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002ccf, {[CaseLower] = 0x002ccf,[CaseTitle] = 0x002cce,[CaseUpper] = 0x002cce}, NULL},
+ {0x002cd0, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd1, {[CaseLower] = 0x002cd1,[CaseTitle] = 0x002cd0,[CaseUpper] = 0x002cd0}, NULL},
+ {0x002cd2, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd3, {[CaseLower] = 0x002cd3,[CaseTitle] = 0x002cd2,[CaseUpper] = 0x002cd2}, NULL},
+ {0x002cd4, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd5, {[CaseLower] = 0x002cd5,[CaseTitle] = 0x002cd4,[CaseUpper] = 0x002cd4}, NULL},
+ {0x002cd6, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd7, {[CaseLower] = 0x002cd7,[CaseTitle] = 0x002cd6,[CaseUpper] = 0x002cd6}, NULL},
+ {0x002cd8, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cd9, {[CaseLower] = 0x002cd9,[CaseTitle] = 0x002cd8,[CaseUpper] = 0x002cd8}, NULL},
+ {0x002cda, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdb, {[CaseLower] = 0x002cdb,[CaseTitle] = 0x002cda,[CaseUpper] = 0x002cda}, NULL},
+ {0x002cdc, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cdd, {[CaseLower] = 0x002cdd,[CaseTitle] = 0x002cdc,[CaseUpper] = 0x002cdc}, NULL},
+ {0x002cde, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002cdf, {[CaseLower] = 0x002cdf,[CaseTitle] = 0x002cde,[CaseUpper] = 0x002cde}, NULL},
+ {0x002ce0, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce1, {[CaseLower] = 0x002ce1,[CaseTitle] = 0x002ce0,[CaseUpper] = 0x002ce0}, NULL},
+ {0x002ce2, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ce3, {[CaseLower] = 0x002ce3,[CaseTitle] = 0x002ce2,[CaseUpper] = 0x002ce2}, NULL},
+ {0x002ceb, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002cec, {[CaseLower] = 0x002cec,[CaseTitle] = 0x002ceb,[CaseUpper] = 0x002ceb}, NULL},
+ {0x002ced, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cee, {[CaseLower] = 0x002cee,[CaseTitle] = 0x002ced,[CaseUpper] = 0x002ced}, NULL},
+ {0x002cf2, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002cf3, {[CaseLower] = 0x002cf3,[CaseTitle] = 0x002cf2,[CaseUpper] = 0x002cf2}, NULL},
+ {0x002d00, {[CaseLower] = 0x002d00,[CaseTitle] = 0x0010a0,[CaseUpper] = 0x0010a0}, NULL},
+ {0x002d01, {[CaseLower] = 0x002d01,[CaseTitle] = 0x0010a1,[CaseUpper] = 0x0010a1}, NULL},
+ {0x002d02, {[CaseLower] = 0x002d02,[CaseTitle] = 0x0010a2,[CaseUpper] = 0x0010a2}, NULL},
+ {0x002d03, {[CaseLower] = 0x002d03,[CaseTitle] = 0x0010a3,[CaseUpper] = 0x0010a3}, NULL},
+ {0x002d04, {[CaseLower] = 0x002d04,[CaseTitle] = 0x0010a4,[CaseUpper] = 0x0010a4}, NULL},
+ {0x002d05, {[CaseLower] = 0x002d05,[CaseTitle] = 0x0010a5,[CaseUpper] = 0x0010a5}, NULL},
+ {0x002d06, {[CaseLower] = 0x002d06,[CaseTitle] = 0x0010a6,[CaseUpper] = 0x0010a6}, NULL},
+ {0x002d07, {[CaseLower] = 0x002d07,[CaseTitle] = 0x0010a7,[CaseUpper] = 0x0010a7}, NULL},
+ {0x002d08, {[CaseLower] = 0x002d08,[CaseTitle] = 0x0010a8,[CaseUpper] = 0x0010a8}, NULL},
+ {0x002d09, {[CaseLower] = 0x002d09,[CaseTitle] = 0x0010a9,[CaseUpper] = 0x0010a9}, NULL},
+ {0x002d0a, {[CaseLower] = 0x002d0a,[CaseTitle] = 0x0010aa,[CaseUpper] = 0x0010aa}, NULL},
+ {0x002d0b, {[CaseLower] = 0x002d0b,[CaseTitle] = 0x0010ab,[CaseUpper] = 0x0010ab}, NULL},
+ {0x002d0c, {[CaseLower] = 0x002d0c,[CaseTitle] = 0x0010ac,[CaseUpper] = 0x0010ac}, NULL},
+ {0x002d0d, {[CaseLower] = 0x002d0d,[CaseTitle] = 0x0010ad,[CaseUpper] = 0x0010ad}, NULL},
+ {0x002d0e, {[CaseLower] = 0x002d0e,[CaseTitle] = 0x0010ae,[CaseUpper] = 0x0010ae}, NULL},
+ {0x002d0f, {[CaseLower] = 0x002d0f,[CaseTitle] = 0x0010af,[CaseUpper] = 0x0010af}, NULL},
+ {0x002d10, {[CaseLower] = 0x002d10,[CaseTitle] = 0x0010b0,[CaseUpper] = 0x0010b0}, NULL},
+ {0x002d11, {[CaseLower] = 0x002d11,[CaseTitle] = 0x0010b1,[CaseUpper] = 0x0010b1}, NULL},
+ {0x002d12, {[CaseLower] = 0x002d12,[CaseTitle] = 0x0010b2,[CaseUpper] = 0x0010b2}, NULL},
+ {0x002d13, {[CaseLower] = 0x002d13,[CaseTitle] = 0x0010b3,[CaseUpper] = 0x0010b3}, NULL},
+ {0x002d14, {[CaseLower] = 0x002d14,[CaseTitle] = 0x0010b4,[CaseUpper] = 0x0010b4}, NULL},
+ {0x002d15, {[CaseLower] = 0x002d15,[CaseTitle] = 0x0010b5,[CaseUpper] = 0x0010b5}, NULL},
+ {0x002d16, {[CaseLower] = 0x002d16,[CaseTitle] = 0x0010b6,[CaseUpper] = 0x0010b6}, NULL},
+ {0x002d17, {[CaseLower] = 0x002d17,[CaseTitle] = 0x0010b7,[CaseUpper] = 0x0010b7}, NULL},
+ {0x002d18, {[CaseLower] = 0x002d18,[CaseTitle] = 0x0010b8,[CaseUpper] = 0x0010b8}, NULL},
+ {0x002d19, {[CaseLower] = 0x002d19,[CaseTitle] = 0x0010b9,[CaseUpper] = 0x0010b9}, NULL},
+ {0x002d1a, {[CaseLower] = 0x002d1a,[CaseTitle] = 0x0010ba,[CaseUpper] = 0x0010ba}, NULL},
+ {0x002d1b, {[CaseLower] = 0x002d1b,[CaseTitle] = 0x0010bb,[CaseUpper] = 0x0010bb}, NULL},
+ {0x002d1c, {[CaseLower] = 0x002d1c,[CaseTitle] = 0x0010bc,[CaseUpper] = 0x0010bc}, NULL},
+ {0x002d1d, {[CaseLower] = 0x002d1d,[CaseTitle] = 0x0010bd,[CaseUpper] = 0x0010bd}, NULL},
+ {0x002d1e, {[CaseLower] = 0x002d1e,[CaseTitle] = 0x0010be,[CaseUpper] = 0x0010be}, NULL},
+ {0x002d1f, {[CaseLower] = 0x002d1f,[CaseTitle] = 0x0010bf,[CaseUpper] = 0x0010bf}, NULL},
+ {0x002d20, {[CaseLower] = 0x002d20,[CaseTitle] = 0x0010c0,[CaseUpper] = 0x0010c0}, NULL},
+ {0x002d21, {[CaseLower] = 0x002d21,[CaseTitle] = 0x0010c1,[CaseUpper] = 0x0010c1}, NULL},
+ {0x002d22, {[CaseLower] = 0x002d22,[CaseTitle] = 0x0010c2,[CaseUpper] = 0x0010c2}, NULL},
+ {0x002d23, {[CaseLower] = 0x002d23,[CaseTitle] = 0x0010c3,[CaseUpper] = 0x0010c3}, NULL},
+ {0x002d24, {[CaseLower] = 0x002d24,[CaseTitle] = 0x0010c4,[CaseUpper] = 0x0010c4}, NULL},
+ {0x002d25, {[CaseLower] = 0x002d25,[CaseTitle] = 0x0010c5,[CaseUpper] = 0x0010c5}, NULL},
+ {0x002d27, {[CaseLower] = 0x002d27,[CaseTitle] = 0x0010c7,[CaseUpper] = 0x0010c7}, NULL},
+ {0x002d2d, {[CaseLower] = 0x002d2d,[CaseTitle] = 0x0010cd,[CaseUpper] = 0x0010cd}, NULL},
+ {0x00a640, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a641, {[CaseLower] = 0x00a641,[CaseTitle] = 0x00a640,[CaseUpper] = 0x00a640}, NULL},
+ {0x00a642, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a643, {[CaseLower] = 0x00a643,[CaseTitle] = 0x00a642,[CaseUpper] = 0x00a642}, NULL},
+ {0x00a644, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a645, {[CaseLower] = 0x00a645,[CaseTitle] = 0x00a644,[CaseUpper] = 0x00a644}, NULL},
+ {0x00a646, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a647, {[CaseLower] = 0x00a647,[CaseTitle] = 0x00a646,[CaseUpper] = 0x00a646}, NULL},
+ {0x00a648, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a649, {[CaseLower] = 0x00a649,[CaseTitle] = 0x00a648,[CaseUpper] = 0x00a648}, NULL},
+ {0x00a64a, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64b, {[CaseLower] = 0x00a64b,[CaseTitle] = 0x00a64a,[CaseUpper] = 0x00a64a}, NULL},
+ {0x00a64c, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64d, {[CaseLower] = 0x00a64d,[CaseTitle] = 0x00a64c,[CaseUpper] = 0x00a64c}, NULL},
+ {0x00a64e, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a64f, {[CaseLower] = 0x00a64f,[CaseTitle] = 0x00a64e,[CaseUpper] = 0x00a64e}, NULL},
+ {0x00a650, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a651, {[CaseLower] = 0x00a651,[CaseTitle] = 0x00a650,[CaseUpper] = 0x00a650}, NULL},
+ {0x00a652, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a653, {[CaseLower] = 0x00a653,[CaseTitle] = 0x00a652,[CaseUpper] = 0x00a652}, NULL},
+ {0x00a654, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a655, {[CaseLower] = 0x00a655,[CaseTitle] = 0x00a654,[CaseUpper] = 0x00a654}, NULL},
+ {0x00a656, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a657, {[CaseLower] = 0x00a657,[CaseTitle] = 0x00a656,[CaseUpper] = 0x00a656}, NULL},
+ {0x00a658, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a659, {[CaseLower] = 0x00a659,[CaseTitle] = 0x00a658,[CaseUpper] = 0x00a658}, NULL},
+ {0x00a65a, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65b, {[CaseLower] = 0x00a65b,[CaseTitle] = 0x00a65a,[CaseUpper] = 0x00a65a}, NULL},
+ {0x00a65c, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65d, {[CaseLower] = 0x00a65d,[CaseTitle] = 0x00a65c,[CaseUpper] = 0x00a65c}, NULL},
+ {0x00a65e, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a65f, {[CaseLower] = 0x00a65f,[CaseTitle] = 0x00a65e,[CaseUpper] = 0x00a65e}, NULL},
+ {0x00a660, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a661, {[CaseLower] = 0x00a661,[CaseTitle] = 0x00a660,[CaseUpper] = 0x00a660}, NULL},
+ {0x00a662, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a663, {[CaseLower] = 0x00a663,[CaseTitle] = 0x00a662,[CaseUpper] = 0x00a662}, NULL},
+ {0x00a664, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a665, {[CaseLower] = 0x00a665,[CaseTitle] = 0x00a664,[CaseUpper] = 0x00a664}, NULL},
+ {0x00a666, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a667, {[CaseLower] = 0x00a667,[CaseTitle] = 0x00a666,[CaseUpper] = 0x00a666}, NULL},
+ {0x00a668, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a669, {[CaseLower] = 0x00a669,[CaseTitle] = 0x00a668,[CaseUpper] = 0x00a668}, NULL},
+ {0x00a66a, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66b, {[CaseLower] = 0x00a66b,[CaseTitle] = 0x00a66a,[CaseUpper] = 0x00a66a}, NULL},
+ {0x00a66c, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a66d, {[CaseLower] = 0x00a66d,[CaseTitle] = 0x00a66c,[CaseUpper] = 0x00a66c}, NULL},
+ {0x00a680, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a681, {[CaseLower] = 0x00a681,[CaseTitle] = 0x00a680,[CaseUpper] = 0x00a680}, NULL},
+ {0x00a682, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a683, {[CaseLower] = 0x00a683,[CaseTitle] = 0x00a682,[CaseUpper] = 0x00a682}, NULL},
+ {0x00a684, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a685, {[CaseLower] = 0x00a685,[CaseTitle] = 0x00a684,[CaseUpper] = 0x00a684}, NULL},
+ {0x00a686, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a687, {[CaseLower] = 0x00a687,[CaseTitle] = 0x00a686,[CaseUpper] = 0x00a686}, NULL},
+ {0x00a688, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a689, {[CaseLower] = 0x00a689,[CaseTitle] = 0x00a688,[CaseUpper] = 0x00a688}, NULL},
+ {0x00a68a, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68b, {[CaseLower] = 0x00a68b,[CaseTitle] = 0x00a68a,[CaseUpper] = 0x00a68a}, NULL},
+ {0x00a68c, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68d, {[CaseLower] = 0x00a68d,[CaseTitle] = 0x00a68c,[CaseUpper] = 0x00a68c}, NULL},
+ {0x00a68e, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a68f, {[CaseLower] = 0x00a68f,[CaseTitle] = 0x00a68e,[CaseUpper] = 0x00a68e}, NULL},
+ {0x00a690, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a691, {[CaseLower] = 0x00a691,[CaseTitle] = 0x00a690,[CaseUpper] = 0x00a690}, NULL},
+ {0x00a692, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a693, {[CaseLower] = 0x00a693,[CaseTitle] = 0x00a692,[CaseUpper] = 0x00a692}, NULL},
+ {0x00a694, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a695, {[CaseLower] = 0x00a695,[CaseTitle] = 0x00a694,[CaseUpper] = 0x00a694}, NULL},
+ {0x00a696, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a697, {[CaseLower] = 0x00a697,[CaseTitle] = 0x00a696,[CaseUpper] = 0x00a696}, NULL},
+ {0x00a698, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a699, {[CaseLower] = 0x00a699,[CaseTitle] = 0x00a698,[CaseUpper] = 0x00a698}, NULL},
+ {0x00a69a, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a69b, {[CaseLower] = 0x00a69b,[CaseTitle] = 0x00a69a,[CaseUpper] = 0x00a69a}, NULL},
+ {0x00a722, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a723, {[CaseLower] = 0x00a723,[CaseTitle] = 0x00a722,[CaseUpper] = 0x00a722}, NULL},
+ {0x00a724, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a725, {[CaseLower] = 0x00a725,[CaseTitle] = 0x00a724,[CaseUpper] = 0x00a724}, NULL},
+ {0x00a726, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a727, {[CaseLower] = 0x00a727,[CaseTitle] = 0x00a726,[CaseUpper] = 0x00a726}, NULL},
+ {0x00a728, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a729, {[CaseLower] = 0x00a729,[CaseTitle] = 0x00a728,[CaseUpper] = 0x00a728}, NULL},
+ {0x00a72a, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72b, {[CaseLower] = 0x00a72b,[CaseTitle] = 0x00a72a,[CaseUpper] = 0x00a72a}, NULL},
+ {0x00a72c, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72d, {[CaseLower] = 0x00a72d,[CaseTitle] = 0x00a72c,[CaseUpper] = 0x00a72c}, NULL},
+ {0x00a72e, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a72f, {[CaseLower] = 0x00a72f,[CaseTitle] = 0x00a72e,[CaseUpper] = 0x00a72e}, NULL},
+ {0x00a732, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a733, {[CaseLower] = 0x00a733,[CaseTitle] = 0x00a732,[CaseUpper] = 0x00a732}, NULL},
+ {0x00a734, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a735, {[CaseLower] = 0x00a735,[CaseTitle] = 0x00a734,[CaseUpper] = 0x00a734}, NULL},
+ {0x00a736, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a737, {[CaseLower] = 0x00a737,[CaseTitle] = 0x00a736,[CaseUpper] = 0x00a736}, NULL},
+ {0x00a738, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a739, {[CaseLower] = 0x00a739,[CaseTitle] = 0x00a738,[CaseUpper] = 0x00a738}, NULL},
+ {0x00a73a, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73b, {[CaseLower] = 0x00a73b,[CaseTitle] = 0x00a73a,[CaseUpper] = 0x00a73a}, NULL},
+ {0x00a73c, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73d, {[CaseLower] = 0x00a73d,[CaseTitle] = 0x00a73c,[CaseUpper] = 0x00a73c}, NULL},
+ {0x00a73e, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a73f, {[CaseLower] = 0x00a73f,[CaseTitle] = 0x00a73e,[CaseUpper] = 0x00a73e}, NULL},
+ {0x00a740, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a741, {[CaseLower] = 0x00a741,[CaseTitle] = 0x00a740,[CaseUpper] = 0x00a740}, NULL},
+ {0x00a742, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a743, {[CaseLower] = 0x00a743,[CaseTitle] = 0x00a742,[CaseUpper] = 0x00a742}, NULL},
+ {0x00a744, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a745, {[CaseLower] = 0x00a745,[CaseTitle] = 0x00a744,[CaseUpper] = 0x00a744}, NULL},
+ {0x00a746, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a747, {[CaseLower] = 0x00a747,[CaseTitle] = 0x00a746,[CaseUpper] = 0x00a746}, NULL},
+ {0x00a748, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a749, {[CaseLower] = 0x00a749,[CaseTitle] = 0x00a748,[CaseUpper] = 0x00a748}, NULL},
+ {0x00a74a, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74b, {[CaseLower] = 0x00a74b,[CaseTitle] = 0x00a74a,[CaseUpper] = 0x00a74a}, NULL},
+ {0x00a74c, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74d, {[CaseLower] = 0x00a74d,[CaseTitle] = 0x00a74c,[CaseUpper] = 0x00a74c}, NULL},
+ {0x00a74e, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a74f, {[CaseLower] = 0x00a74f,[CaseTitle] = 0x00a74e,[CaseUpper] = 0x00a74e}, NULL},
+ {0x00a750, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a751, {[CaseLower] = 0x00a751,[CaseTitle] = 0x00a750,[CaseUpper] = 0x00a750}, NULL},
+ {0x00a752, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a753, {[CaseLower] = 0x00a753,[CaseTitle] = 0x00a752,[CaseUpper] = 0x00a752}, NULL},
+ {0x00a754, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a755, {[CaseLower] = 0x00a755,[CaseTitle] = 0x00a754,[CaseUpper] = 0x00a754}, NULL},
+ {0x00a756, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a757, {[CaseLower] = 0x00a757,[CaseTitle] = 0x00a756,[CaseUpper] = 0x00a756}, NULL},
+ {0x00a758, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a759, {[CaseLower] = 0x00a759,[CaseTitle] = 0x00a758,[CaseUpper] = 0x00a758}, NULL},
+ {0x00a75a, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75b, {[CaseLower] = 0x00a75b,[CaseTitle] = 0x00a75a,[CaseUpper] = 0x00a75a}, NULL},
+ {0x00a75c, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75d, {[CaseLower] = 0x00a75d,[CaseTitle] = 0x00a75c,[CaseUpper] = 0x00a75c}, NULL},
+ {0x00a75e, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a75f, {[CaseLower] = 0x00a75f,[CaseTitle] = 0x00a75e,[CaseUpper] = 0x00a75e}, NULL},
+ {0x00a760, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a761, {[CaseLower] = 0x00a761,[CaseTitle] = 0x00a760,[CaseUpper] = 0x00a760}, NULL},
+ {0x00a762, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a763, {[CaseLower] = 0x00a763,[CaseTitle] = 0x00a762,[CaseUpper] = 0x00a762}, NULL},
+ {0x00a764, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a765, {[CaseLower] = 0x00a765,[CaseTitle] = 0x00a764,[CaseUpper] = 0x00a764}, NULL},
+ {0x00a766, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a767, {[CaseLower] = 0x00a767,[CaseTitle] = 0x00a766,[CaseUpper] = 0x00a766}, NULL},
+ {0x00a768, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a769, {[CaseLower] = 0x00a769,[CaseTitle] = 0x00a768,[CaseUpper] = 0x00a768}, NULL},
+ {0x00a76a, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76b, {[CaseLower] = 0x00a76b,[CaseTitle] = 0x00a76a,[CaseUpper] = 0x00a76a}, NULL},
+ {0x00a76c, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76d, {[CaseLower] = 0x00a76d,[CaseTitle] = 0x00a76c,[CaseUpper] = 0x00a76c}, NULL},
+ {0x00a76e, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a76f, {[CaseLower] = 0x00a76f,[CaseTitle] = 0x00a76e,[CaseUpper] = 0x00a76e}, NULL},
+ {0x00a779, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77a, {[CaseLower] = 0x00a77a,[CaseTitle] = 0x00a779,[CaseUpper] = 0x00a779}, NULL},
+ {0x00a77b, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77c, {[CaseLower] = 0x00a77c,[CaseTitle] = 0x00a77b,[CaseUpper] = 0x00a77b}, NULL},
+ {0x00a77d, {[CaseLower] = 0x001d79,[CaseTitle] = 0x00a77d,[CaseUpper] = 0x00a77d}, NULL},
+ {0x00a77e, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a77f, {[CaseLower] = 0x00a77f,[CaseTitle] = 0x00a77e,[CaseUpper] = 0x00a77e}, NULL},
+ {0x00a780, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a781, {[CaseLower] = 0x00a781,[CaseTitle] = 0x00a780,[CaseUpper] = 0x00a780}, NULL},
+ {0x00a782, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a783, {[CaseLower] = 0x00a783,[CaseTitle] = 0x00a782,[CaseUpper] = 0x00a782}, NULL},
+ {0x00a784, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a785, {[CaseLower] = 0x00a785,[CaseTitle] = 0x00a784,[CaseUpper] = 0x00a784}, NULL},
+ {0x00a786, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a787, {[CaseLower] = 0x00a787,[CaseTitle] = 0x00a786,[CaseUpper] = 0x00a786}, NULL},
+ {0x00a78b, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78c, {[CaseLower] = 0x00a78c,[CaseTitle] = 0x00a78b,[CaseUpper] = 0x00a78b}, NULL},
+ {0x00a78d, {[CaseLower] = 0x000265,[CaseTitle] = 0x00a78d,[CaseUpper] = 0x00a78d}, NULL},
+ {0x00a790, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a791, {[CaseLower] = 0x00a791,[CaseTitle] = 0x00a790,[CaseUpper] = 0x00a790}, NULL},
+ {0x00a792, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a793, {[CaseLower] = 0x00a793,[CaseTitle] = 0x00a792,[CaseUpper] = 0x00a792}, NULL},
+ {0x00a794, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a796, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a797, {[CaseLower] = 0x00a797,[CaseTitle] = 0x00a796,[CaseUpper] = 0x00a796}, NULL},
+ {0x00a798, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a799, {[CaseLower] = 0x00a799,[CaseTitle] = 0x00a798,[CaseUpper] = 0x00a798}, NULL},
+ {0x00a79a, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79b, {[CaseLower] = 0x00a79b,[CaseTitle] = 0x00a79a,[CaseUpper] = 0x00a79a}, NULL},
+ {0x00a79c, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79d, {[CaseLower] = 0x00a79d,[CaseTitle] = 0x00a79c,[CaseUpper] = 0x00a79c}, NULL},
+ {0x00a79e, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a79f, {[CaseLower] = 0x00a79f,[CaseTitle] = 0x00a79e,[CaseUpper] = 0x00a79e}, NULL},
+ {0x00a7a0, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a1, {[CaseLower] = 0x00a7a1,[CaseTitle] = 0x00a7a0,[CaseUpper] = 0x00a7a0}, NULL},
+ {0x00a7a2, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a3, {[CaseLower] = 0x00a7a3,[CaseTitle] = 0x00a7a2,[CaseUpper] = 0x00a7a2}, NULL},
+ {0x00a7a4, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a5, {[CaseLower] = 0x00a7a5,[CaseTitle] = 0x00a7a4,[CaseUpper] = 0x00a7a4}, NULL},
+ {0x00a7a6, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a7, {[CaseLower] = 0x00a7a7,[CaseTitle] = 0x00a7a6,[CaseUpper] = 0x00a7a6}, NULL},
+ {0x00a7a8, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7a9, {[CaseLower] = 0x00a7a9,[CaseTitle] = 0x00a7a8,[CaseUpper] = 0x00a7a8}, NULL},
+ {0x00a7aa, {[CaseLower] = 0x000266,[CaseTitle] = 0x00a7aa,[CaseUpper] = 0x00a7aa}, NULL},
+ {0x00a7ab, {[CaseLower] = 0x00025c,[CaseTitle] = 0x00a7ab,[CaseUpper] = 0x00a7ab}, NULL},
+ {0x00a7ac, {[CaseLower] = 0x000261,[CaseTitle] = 0x00a7ac,[CaseUpper] = 0x00a7ac}, NULL},
+ {0x00a7ad, {[CaseLower] = 0x00026c,[CaseTitle] = 0x00a7ad,[CaseUpper] = 0x00a7ad}, NULL},
+ {0x00a7ae, {[CaseLower] = 0x00026a,[CaseTitle] = 0x00a7ae,[CaseUpper] = 0x00a7ae}, NULL},
+ {0x00a7b0, {[CaseLower] = 0x00029e,[CaseTitle] = 0x00a7b0,[CaseUpper] = 0x00a7b0}, NULL},
+ {0x00a7b1, {[CaseLower] = 0x000287,[CaseTitle] = 0x00a7b1,[CaseUpper] = 0x00a7b1}, NULL},
+ {0x00a7b2, {[CaseLower] = 0x00029d,[CaseTitle] = 0x00a7b2,[CaseUpper] = 0x00a7b2}, NULL},
+ {0x00a7b3, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00a7b4, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b5, {[CaseLower] = 0x00a7b5,[CaseTitle] = 0x00a7b4,[CaseUpper] = 0x00a7b4}, NULL},
+ {0x00a7b6, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b7, {[CaseLower] = 0x00a7b7,[CaseTitle] = 0x00a7b6,[CaseUpper] = 0x00a7b6}, NULL},
+ {0x00a7b8, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7b9, {[CaseLower] = 0x00a7b9,[CaseTitle] = 0x00a7b8,[CaseUpper] = 0x00a7b8}, NULL},
+ {0x00a7ba, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bb, {[CaseLower] = 0x00a7bb,[CaseTitle] = 0x00a7ba,[CaseUpper] = 0x00a7ba}, NULL},
+ {0x00a7bc, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7bd, {[CaseLower] = 0x00a7bd,[CaseTitle] = 0x00a7bc,[CaseUpper] = 0x00a7bc}, NULL},
+ {0x00a7be, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7bf, {[CaseLower] = 0x00a7bf,[CaseTitle] = 0x00a7be,[CaseUpper] = 0x00a7be}, NULL},
+ {0x00a7c0, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c1, {[CaseLower] = 0x00a7c1,[CaseTitle] = 0x00a7c0,[CaseUpper] = 0x00a7c0}, NULL},
+ {0x00a7c2, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c3, {[CaseLower] = 0x00a7c3,[CaseTitle] = 0x00a7c2,[CaseUpper] = 0x00a7c2}, NULL},
+ {0x00a7c4, {[CaseLower] = 0x00a794,[CaseTitle] = 0x00a7c4,[CaseUpper] = 0x00a7c4}, NULL},
+ {0x00a7c5, {[CaseLower] = 0x000282,[CaseTitle] = 0x00a7c5,[CaseUpper] = 0x00a7c5}, NULL},
+ {0x00a7c6, {[CaseLower] = 0x001d8e,[CaseTitle] = 0x00a7c6,[CaseUpper] = 0x00a7c6}, NULL},
+ {0x00a7c7, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c8, {[CaseLower] = 0x00a7c8,[CaseTitle] = 0x00a7c7,[CaseUpper] = 0x00a7c7}, NULL},
+ {0x00a7c9, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7ca, {[CaseLower] = 0x00a7ca,[CaseTitle] = 0x00a7c9,[CaseUpper] = 0x00a7c9}, NULL},
+ {0x00a7d0, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d1, {[CaseLower] = 0x00a7d1,[CaseTitle] = 0x00a7d0,[CaseUpper] = 0x00a7d0}, NULL},
+ {0x00a7d6, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d7, {[CaseLower] = 0x00a7d7,[CaseTitle] = 0x00a7d6,[CaseUpper] = 0x00a7d6}, NULL},
+ {0x00a7d8, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7d9, {[CaseLower] = 0x00a7d9,[CaseTitle] = 0x00a7d8,[CaseUpper] = 0x00a7d8}, NULL},
+ {0x00a7f5, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00a7f6, {[CaseLower] = 0x00a7f6,[CaseTitle] = 0x00a7f5,[CaseUpper] = 0x00a7f5}, NULL},
+ {0x00ab53, {[CaseLower] = 0x00ab53,[CaseTitle] = 0x00a7b3,[CaseUpper] = 0x00a7b3}, NULL},
+ {0x00ab70, {[CaseLower] = 0x00ab70,[CaseTitle] = 0x0013a0,[CaseUpper] = 0x0013a0}, NULL},
+ {0x00ab71, {[CaseLower] = 0x00ab71,[CaseTitle] = 0x0013a1,[CaseUpper] = 0x0013a1}, NULL},
+ {0x00ab72, {[CaseLower] = 0x00ab72,[CaseTitle] = 0x0013a2,[CaseUpper] = 0x0013a2}, NULL},
+ {0x00ab73, {[CaseLower] = 0x00ab73,[CaseTitle] = 0x0013a3,[CaseUpper] = 0x0013a3}, NULL},
+ {0x00ab74, {[CaseLower] = 0x00ab74,[CaseTitle] = 0x0013a4,[CaseUpper] = 0x0013a4}, NULL},
+ {0x00ab75, {[CaseLower] = 0x00ab75,[CaseTitle] = 0x0013a5,[CaseUpper] = 0x0013a5}, NULL},
+ {0x00ab76, {[CaseLower] = 0x00ab76,[CaseTitle] = 0x0013a6,[CaseUpper] = 0x0013a6}, NULL},
+ {0x00ab77, {[CaseLower] = 0x00ab77,[CaseTitle] = 0x0013a7,[CaseUpper] = 0x0013a7}, NULL},
+ {0x00ab78, {[CaseLower] = 0x00ab78,[CaseTitle] = 0x0013a8,[CaseUpper] = 0x0013a8}, NULL},
+ {0x00ab79, {[CaseLower] = 0x00ab79,[CaseTitle] = 0x0013a9,[CaseUpper] = 0x0013a9}, NULL},
+ {0x00ab7a, {[CaseLower] = 0x00ab7a,[CaseTitle] = 0x0013aa,[CaseUpper] = 0x0013aa}, NULL},
+ {0x00ab7b, {[CaseLower] = 0x00ab7b,[CaseTitle] = 0x0013ab,[CaseUpper] = 0x0013ab}, NULL},
+ {0x00ab7c, {[CaseLower] = 0x00ab7c,[CaseTitle] = 0x0013ac,[CaseUpper] = 0x0013ac}, NULL},
+ {0x00ab7d, {[CaseLower] = 0x00ab7d,[CaseTitle] = 0x0013ad,[CaseUpper] = 0x0013ad}, NULL},
+ {0x00ab7e, {[CaseLower] = 0x00ab7e,[CaseTitle] = 0x0013ae,[CaseUpper] = 0x0013ae}, NULL},
+ {0x00ab7f, {[CaseLower] = 0x00ab7f,[CaseTitle] = 0x0013af,[CaseUpper] = 0x0013af}, NULL},
+ {0x00ab80, {[CaseLower] = 0x00ab80,[CaseTitle] = 0x0013b0,[CaseUpper] = 0x0013b0}, NULL},
+ {0x00ab81, {[CaseLower] = 0x00ab81,[CaseTitle] = 0x0013b1,[CaseUpper] = 0x0013b1}, NULL},
+ {0x00ab82, {[CaseLower] = 0x00ab82,[CaseTitle] = 0x0013b2,[CaseUpper] = 0x0013b2}, NULL},
+ {0x00ab83, {[CaseLower] = 0x00ab83,[CaseTitle] = 0x0013b3,[CaseUpper] = 0x0013b3}, NULL},
+ {0x00ab84, {[CaseLower] = 0x00ab84,[CaseTitle] = 0x0013b4,[CaseUpper] = 0x0013b4}, NULL},
+ {0x00ab85, {[CaseLower] = 0x00ab85,[CaseTitle] = 0x0013b5,[CaseUpper] = 0x0013b5}, NULL},
+ {0x00ab86, {[CaseLower] = 0x00ab86,[CaseTitle] = 0x0013b6,[CaseUpper] = 0x0013b6}, NULL},
+ {0x00ab87, {[CaseLower] = 0x00ab87,[CaseTitle] = 0x0013b7,[CaseUpper] = 0x0013b7}, NULL},
+ {0x00ab88, {[CaseLower] = 0x00ab88,[CaseTitle] = 0x0013b8,[CaseUpper] = 0x0013b8}, NULL},
+ {0x00ab89, {[CaseLower] = 0x00ab89,[CaseTitle] = 0x0013b9,[CaseUpper] = 0x0013b9}, NULL},
+ {0x00ab8a, {[CaseLower] = 0x00ab8a,[CaseTitle] = 0x0013ba,[CaseUpper] = 0x0013ba}, NULL},
+ {0x00ab8b, {[CaseLower] = 0x00ab8b,[CaseTitle] = 0x0013bb,[CaseUpper] = 0x0013bb}, NULL},
+ {0x00ab8c, {[CaseLower] = 0x00ab8c,[CaseTitle] = 0x0013bc,[CaseUpper] = 0x0013bc}, NULL},
+ {0x00ab8d, {[CaseLower] = 0x00ab8d,[CaseTitle] = 0x0013bd,[CaseUpper] = 0x0013bd}, NULL},
+ {0x00ab8e, {[CaseLower] = 0x00ab8e,[CaseTitle] = 0x0013be,[CaseUpper] = 0x0013be}, NULL},
+ {0x00ab8f, {[CaseLower] = 0x00ab8f,[CaseTitle] = 0x0013bf,[CaseUpper] = 0x0013bf}, NULL},
+ {0x00ab90, {[CaseLower] = 0x00ab90,[CaseTitle] = 0x0013c0,[CaseUpper] = 0x0013c0}, NULL},
+ {0x00ab91, {[CaseLower] = 0x00ab91,[CaseTitle] = 0x0013c1,[CaseUpper] = 0x0013c1}, NULL},
+ {0x00ab92, {[CaseLower] = 0x00ab92,[CaseTitle] = 0x0013c2,[CaseUpper] = 0x0013c2}, NULL},
+ {0x00ab93, {[CaseLower] = 0x00ab93,[CaseTitle] = 0x0013c3,[CaseUpper] = 0x0013c3}, NULL},
+ {0x00ab94, {[CaseLower] = 0x00ab94,[CaseTitle] = 0x0013c4,[CaseUpper] = 0x0013c4}, NULL},
+ {0x00ab95, {[CaseLower] = 0x00ab95,[CaseTitle] = 0x0013c5,[CaseUpper] = 0x0013c5}, NULL},
+ {0x00ab96, {[CaseLower] = 0x00ab96,[CaseTitle] = 0x0013c6,[CaseUpper] = 0x0013c6}, NULL},
+ {0x00ab97, {[CaseLower] = 0x00ab97,[CaseTitle] = 0x0013c7,[CaseUpper] = 0x0013c7}, NULL},
+ {0x00ab98, {[CaseLower] = 0x00ab98,[CaseTitle] = 0x0013c8,[CaseUpper] = 0x0013c8}, NULL},
+ {0x00ab99, {[CaseLower] = 0x00ab99,[CaseTitle] = 0x0013c9,[CaseUpper] = 0x0013c9}, NULL},
+ {0x00ab9a, {[CaseLower] = 0x00ab9a,[CaseTitle] = 0x0013ca,[CaseUpper] = 0x0013ca}, NULL},
+ {0x00ab9b, {[CaseLower] = 0x00ab9b,[CaseTitle] = 0x0013cb,[CaseUpper] = 0x0013cb}, NULL},
+ {0x00ab9c, {[CaseLower] = 0x00ab9c,[CaseTitle] = 0x0013cc,[CaseUpper] = 0x0013cc}, NULL},
+ {0x00ab9d, {[CaseLower] = 0x00ab9d,[CaseTitle] = 0x0013cd,[CaseUpper] = 0x0013cd}, NULL},
+ {0x00ab9e, {[CaseLower] = 0x00ab9e,[CaseTitle] = 0x0013ce,[CaseUpper] = 0x0013ce}, NULL},
+ {0x00ab9f, {[CaseLower] = 0x00ab9f,[CaseTitle] = 0x0013cf,[CaseUpper] = 0x0013cf}, NULL},
+ {0x00aba0, {[CaseLower] = 0x00aba0,[CaseTitle] = 0x0013d0,[CaseUpper] = 0x0013d0}, NULL},
+ {0x00aba1, {[CaseLower] = 0x00aba1,[CaseTitle] = 0x0013d1,[CaseUpper] = 0x0013d1}, NULL},
+ {0x00aba2, {[CaseLower] = 0x00aba2,[CaseTitle] = 0x0013d2,[CaseUpper] = 0x0013d2}, NULL},
+ {0x00aba3, {[CaseLower] = 0x00aba3,[CaseTitle] = 0x0013d3,[CaseUpper] = 0x0013d3}, NULL},
+ {0x00aba4, {[CaseLower] = 0x00aba4,[CaseTitle] = 0x0013d4,[CaseUpper] = 0x0013d4}, NULL},
+ {0x00aba5, {[CaseLower] = 0x00aba5,[CaseTitle] = 0x0013d5,[CaseUpper] = 0x0013d5}, NULL},
+ {0x00aba6, {[CaseLower] = 0x00aba6,[CaseTitle] = 0x0013d6,[CaseUpper] = 0x0013d6}, NULL},
+ {0x00aba7, {[CaseLower] = 0x00aba7,[CaseTitle] = 0x0013d7,[CaseUpper] = 0x0013d7}, NULL},
+ {0x00aba8, {[CaseLower] = 0x00aba8,[CaseTitle] = 0x0013d8,[CaseUpper] = 0x0013d8}, NULL},
+ {0x00aba9, {[CaseLower] = 0x00aba9,[CaseTitle] = 0x0013d9,[CaseUpper] = 0x0013d9}, NULL},
+ {0x00abaa, {[CaseLower] = 0x00abaa,[CaseTitle] = 0x0013da,[CaseUpper] = 0x0013da}, NULL},
+ {0x00abab, {[CaseLower] = 0x00abab,[CaseTitle] = 0x0013db,[CaseUpper] = 0x0013db}, NULL},
+ {0x00abac, {[CaseLower] = 0x00abac,[CaseTitle] = 0x0013dc,[CaseUpper] = 0x0013dc}, NULL},
+ {0x00abad, {[CaseLower] = 0x00abad,[CaseTitle] = 0x0013dd,[CaseUpper] = 0x0013dd}, NULL},
+ {0x00abae, {[CaseLower] = 0x00abae,[CaseTitle] = 0x0013de,[CaseUpper] = 0x0013de}, NULL},
+ {0x00abaf, {[CaseLower] = 0x00abaf,[CaseTitle] = 0x0013df,[CaseUpper] = 0x0013df}, NULL},
+ {0x00abb0, {[CaseLower] = 0x00abb0,[CaseTitle] = 0x0013e0,[CaseUpper] = 0x0013e0}, NULL},
+ {0x00abb1, {[CaseLower] = 0x00abb1,[CaseTitle] = 0x0013e1,[CaseUpper] = 0x0013e1}, NULL},
+ {0x00abb2, {[CaseLower] = 0x00abb2,[CaseTitle] = 0x0013e2,[CaseUpper] = 0x0013e2}, NULL},
+ {0x00abb3, {[CaseLower] = 0x00abb3,[CaseTitle] = 0x0013e3,[CaseUpper] = 0x0013e3}, NULL},
+ {0x00abb4, {[CaseLower] = 0x00abb4,[CaseTitle] = 0x0013e4,[CaseUpper] = 0x0013e4}, NULL},
+ {0x00abb5, {[CaseLower] = 0x00abb5,[CaseTitle] = 0x0013e5,[CaseUpper] = 0x0013e5}, NULL},
+ {0x00abb6, {[CaseLower] = 0x00abb6,[CaseTitle] = 0x0013e6,[CaseUpper] = 0x0013e6}, NULL},
+ {0x00abb7, {[CaseLower] = 0x00abb7,[CaseTitle] = 0x0013e7,[CaseUpper] = 0x0013e7}, NULL},
+ {0x00abb8, {[CaseLower] = 0x00abb8,[CaseTitle] = 0x0013e8,[CaseUpper] = 0x0013e8}, NULL},
+ {0x00abb9, {[CaseLower] = 0x00abb9,[CaseTitle] = 0x0013e9,[CaseUpper] = 0x0013e9}, NULL},
+ {0x00abba, {[CaseLower] = 0x00abba,[CaseTitle] = 0x0013ea,[CaseUpper] = 0x0013ea}, NULL},
+ {0x00abbb, {[CaseLower] = 0x00abbb,[CaseTitle] = 0x0013eb,[CaseUpper] = 0x0013eb}, NULL},
+ {0x00abbc, {[CaseLower] = 0x00abbc,[CaseTitle] = 0x0013ec,[CaseUpper] = 0x0013ec}, NULL},
+ {0x00abbd, {[CaseLower] = 0x00abbd,[CaseTitle] = 0x0013ed,[CaseUpper] = 0x0013ed}, NULL},
+ {0x00abbe, {[CaseLower] = 0x00abbe,[CaseTitle] = 0x0013ee,[CaseUpper] = 0x0013ee}, NULL},
+ {0x00abbf, {[CaseLower] = 0x00abbf,[CaseTitle] = 0x0013ef,[CaseUpper] = 0x0013ef}, NULL},
+ {0x00fb00, {[CaseLower] = 0x00fb00,[CaseTitle] = 0x00fb00,[CaseUpper] = 0x00fb00}, &special_case[92]},
+ {0x00fb01, {[CaseLower] = 0x00fb01,[CaseTitle] = 0x00fb01,[CaseUpper] = 0x00fb01}, &special_case[93]},
+ {0x00fb02, {[CaseLower] = 0x00fb02,[CaseTitle] = 0x00fb02,[CaseUpper] = 0x00fb02}, &special_case[94]},
+ {0x00fb03, {[CaseLower] = 0x00fb03,[CaseTitle] = 0x00fb03,[CaseUpper] = 0x00fb03}, &special_case[95]},
+ {0x00fb04, {[CaseLower] = 0x00fb04,[CaseTitle] = 0x00fb04,[CaseUpper] = 0x00fb04}, &special_case[96]},
+ {0x00fb05, {[CaseLower] = 0x00fb05,[CaseTitle] = 0x00fb05,[CaseUpper] = 0x00fb05}, &special_case[97]},
+ {0x00fb06, {[CaseLower] = 0x00fb06,[CaseTitle] = 0x00fb06,[CaseUpper] = 0x00fb06}, &special_case[98]},
+ {0x00fb13, {[CaseLower] = 0x00fb13,[CaseTitle] = 0x00fb13,[CaseUpper] = 0x00fb13}, &special_case[99]},
+ {0x00fb14, {[CaseLower] = 0x00fb14,[CaseTitle] = 0x00fb14,[CaseUpper] = 0x00fb14}, &special_case[100]},
+ {0x00fb15, {[CaseLower] = 0x00fb15,[CaseTitle] = 0x00fb15,[CaseUpper] = 0x00fb15}, &special_case[101]},
+ {0x00fb16, {[CaseLower] = 0x00fb16,[CaseTitle] = 0x00fb16,[CaseUpper] = 0x00fb16}, &special_case[102]},
+ {0x00fb17, {[CaseLower] = 0x00fb17,[CaseTitle] = 0x00fb17,[CaseUpper] = 0x00fb17}, &special_case[103]},
+ {0x00ff21, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff22, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff23, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff24, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff25, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff26, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff27, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff28, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff29, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff2a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff2b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff2c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff2d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff2e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff2f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff30, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff31, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff32, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff33, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff34, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff35, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff36, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff37, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff38, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff39, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff3a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x00ff41, {[CaseLower] = 0x00ff41,[CaseTitle] = 0x00ff21,[CaseUpper] = 0x00ff21}, NULL},
+ {0x00ff42, {[CaseLower] = 0x00ff42,[CaseTitle] = 0x00ff22,[CaseUpper] = 0x00ff22}, NULL},
+ {0x00ff43, {[CaseLower] = 0x00ff43,[CaseTitle] = 0x00ff23,[CaseUpper] = 0x00ff23}, NULL},
+ {0x00ff44, {[CaseLower] = 0x00ff44,[CaseTitle] = 0x00ff24,[CaseUpper] = 0x00ff24}, NULL},
+ {0x00ff45, {[CaseLower] = 0x00ff45,[CaseTitle] = 0x00ff25,[CaseUpper] = 0x00ff25}, NULL},
+ {0x00ff46, {[CaseLower] = 0x00ff46,[CaseTitle] = 0x00ff26,[CaseUpper] = 0x00ff26}, NULL},
+ {0x00ff47, {[CaseLower] = 0x00ff47,[CaseTitle] = 0x00ff27,[CaseUpper] = 0x00ff27}, NULL},
+ {0x00ff48, {[CaseLower] = 0x00ff48,[CaseTitle] = 0x00ff28,[CaseUpper] = 0x00ff28}, NULL},
+ {0x00ff49, {[CaseLower] = 0x00ff49,[CaseTitle] = 0x00ff29,[CaseUpper] = 0x00ff29}, NULL},
+ {0x00ff4a, {[CaseLower] = 0x00ff4a,[CaseTitle] = 0x00ff2a,[CaseUpper] = 0x00ff2a}, NULL},
+ {0x00ff4b, {[CaseLower] = 0x00ff4b,[CaseTitle] = 0x00ff2b,[CaseUpper] = 0x00ff2b}, NULL},
+ {0x00ff4c, {[CaseLower] = 0x00ff4c,[CaseTitle] = 0x00ff2c,[CaseUpper] = 0x00ff2c}, NULL},
+ {0x00ff4d, {[CaseLower] = 0x00ff4d,[CaseTitle] = 0x00ff2d,[CaseUpper] = 0x00ff2d}, NULL},
+ {0x00ff4e, {[CaseLower] = 0x00ff4e,[CaseTitle] = 0x00ff2e,[CaseUpper] = 0x00ff2e}, NULL},
+ {0x00ff4f, {[CaseLower] = 0x00ff4f,[CaseTitle] = 0x00ff2f,[CaseUpper] = 0x00ff2f}, NULL},
+ {0x00ff50, {[CaseLower] = 0x00ff50,[CaseTitle] = 0x00ff30,[CaseUpper] = 0x00ff30}, NULL},
+ {0x00ff51, {[CaseLower] = 0x00ff51,[CaseTitle] = 0x00ff31,[CaseUpper] = 0x00ff31}, NULL},
+ {0x00ff52, {[CaseLower] = 0x00ff52,[CaseTitle] = 0x00ff32,[CaseUpper] = 0x00ff32}, NULL},
+ {0x00ff53, {[CaseLower] = 0x00ff53,[CaseTitle] = 0x00ff33,[CaseUpper] = 0x00ff33}, NULL},
+ {0x00ff54, {[CaseLower] = 0x00ff54,[CaseTitle] = 0x00ff34,[CaseUpper] = 0x00ff34}, NULL},
+ {0x00ff55, {[CaseLower] = 0x00ff55,[CaseTitle] = 0x00ff35,[CaseUpper] = 0x00ff35}, NULL},
+ {0x00ff56, {[CaseLower] = 0x00ff56,[CaseTitle] = 0x00ff36,[CaseUpper] = 0x00ff36}, NULL},
+ {0x00ff57, {[CaseLower] = 0x00ff57,[CaseTitle] = 0x00ff37,[CaseUpper] = 0x00ff37}, NULL},
+ {0x00ff58, {[CaseLower] = 0x00ff58,[CaseTitle] = 0x00ff38,[CaseUpper] = 0x00ff38}, NULL},
+ {0x00ff59, {[CaseLower] = 0x00ff59,[CaseTitle] = 0x00ff39,[CaseUpper] = 0x00ff39}, NULL},
+ {0x00ff5a, {[CaseLower] = 0x00ff5a,[CaseTitle] = 0x00ff3a,[CaseUpper] = 0x00ff3a}, NULL},
+ {0x010400, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010401, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x010402, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x010403, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x010404, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x010405, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x010406, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x010407, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010408, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010409, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x01040a, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x01040b, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x01040c, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x01040d, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x01040e, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x01040f, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010410, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010411, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x010412, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x010413, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x010414, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x010415, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x010416, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x010417, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010418, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010419, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x01041a, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x01041b, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x01041c, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x01041d, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x01041e, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x01041f, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010420, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010421, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x010422, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x010423, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x010424, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x010425, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x010426, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x010427, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x010428, {[CaseLower] = 0x010428,[CaseTitle] = 0x010400,[CaseUpper] = 0x010400}, NULL},
+ {0x010429, {[CaseLower] = 0x010429,[CaseTitle] = 0x010401,[CaseUpper] = 0x010401}, NULL},
+ {0x01042a, {[CaseLower] = 0x01042a,[CaseTitle] = 0x010402,[CaseUpper] = 0x010402}, NULL},
+ {0x01042b, {[CaseLower] = 0x01042b,[CaseTitle] = 0x010403,[CaseUpper] = 0x010403}, NULL},
+ {0x01042c, {[CaseLower] = 0x01042c,[CaseTitle] = 0x010404,[CaseUpper] = 0x010404}, NULL},
+ {0x01042d, {[CaseLower] = 0x01042d,[CaseTitle] = 0x010405,[CaseUpper] = 0x010405}, NULL},
+ {0x01042e, {[CaseLower] = 0x01042e,[CaseTitle] = 0x010406,[CaseUpper] = 0x010406}, NULL},
+ {0x01042f, {[CaseLower] = 0x01042f,[CaseTitle] = 0x010407,[CaseUpper] = 0x010407}, NULL},
+ {0x010430, {[CaseLower] = 0x010430,[CaseTitle] = 0x010408,[CaseUpper] = 0x010408}, NULL},
+ {0x010431, {[CaseLower] = 0x010431,[CaseTitle] = 0x010409,[CaseUpper] = 0x010409}, NULL},
+ {0x010432, {[CaseLower] = 0x010432,[CaseTitle] = 0x01040a,[CaseUpper] = 0x01040a}, NULL},
+ {0x010433, {[CaseLower] = 0x010433,[CaseTitle] = 0x01040b,[CaseUpper] = 0x01040b}, NULL},
+ {0x010434, {[CaseLower] = 0x010434,[CaseTitle] = 0x01040c,[CaseUpper] = 0x01040c}, NULL},
+ {0x010435, {[CaseLower] = 0x010435,[CaseTitle] = 0x01040d,[CaseUpper] = 0x01040d}, NULL},
+ {0x010436, {[CaseLower] = 0x010436,[CaseTitle] = 0x01040e,[CaseUpper] = 0x01040e}, NULL},
+ {0x010437, {[CaseLower] = 0x010437,[CaseTitle] = 0x01040f,[CaseUpper] = 0x01040f}, NULL},
+ {0x010438, {[CaseLower] = 0x010438,[CaseTitle] = 0x010410,[CaseUpper] = 0x010410}, NULL},
+ {0x010439, {[CaseLower] = 0x010439,[CaseTitle] = 0x010411,[CaseUpper] = 0x010411}, NULL},
+ {0x01043a, {[CaseLower] = 0x01043a,[CaseTitle] = 0x010412,[CaseUpper] = 0x010412}, NULL},
+ {0x01043b, {[CaseLower] = 0x01043b,[CaseTitle] = 0x010413,[CaseUpper] = 0x010413}, NULL},
+ {0x01043c, {[CaseLower] = 0x01043c,[CaseTitle] = 0x010414,[CaseUpper] = 0x010414}, NULL},
+ {0x01043d, {[CaseLower] = 0x01043d,[CaseTitle] = 0x010415,[CaseUpper] = 0x010415}, NULL},
+ {0x01043e, {[CaseLower] = 0x01043e,[CaseTitle] = 0x010416,[CaseUpper] = 0x010416}, NULL},
+ {0x01043f, {[CaseLower] = 0x01043f,[CaseTitle] = 0x010417,[CaseUpper] = 0x010417}, NULL},
+ {0x010440, {[CaseLower] = 0x010440,[CaseTitle] = 0x010418,[CaseUpper] = 0x010418}, NULL},
+ {0x010441, {[CaseLower] = 0x010441,[CaseTitle] = 0x010419,[CaseUpper] = 0x010419}, NULL},
+ {0x010442, {[CaseLower] = 0x010442,[CaseTitle] = 0x01041a,[CaseUpper] = 0x01041a}, NULL},
+ {0x010443, {[CaseLower] = 0x010443,[CaseTitle] = 0x01041b,[CaseUpper] = 0x01041b}, NULL},
+ {0x010444, {[CaseLower] = 0x010444,[CaseTitle] = 0x01041c,[CaseUpper] = 0x01041c}, NULL},
+ {0x010445, {[CaseLower] = 0x010445,[CaseTitle] = 0x01041d,[CaseUpper] = 0x01041d}, NULL},
+ {0x010446, {[CaseLower] = 0x010446,[CaseTitle] = 0x01041e,[CaseUpper] = 0x01041e}, NULL},
+ {0x010447, {[CaseLower] = 0x010447,[CaseTitle] = 0x01041f,[CaseUpper] = 0x01041f}, NULL},
+ {0x010448, {[CaseLower] = 0x010448,[CaseTitle] = 0x010420,[CaseUpper] = 0x010420}, NULL},
+ {0x010449, {[CaseLower] = 0x010449,[CaseTitle] = 0x010421,[CaseUpper] = 0x010421}, NULL},
+ {0x01044a, {[CaseLower] = 0x01044a,[CaseTitle] = 0x010422,[CaseUpper] = 0x010422}, NULL},
+ {0x01044b, {[CaseLower] = 0x01044b,[CaseTitle] = 0x010423,[CaseUpper] = 0x010423}, NULL},
+ {0x01044c, {[CaseLower] = 0x01044c,[CaseTitle] = 0x010424,[CaseUpper] = 0x010424}, NULL},
+ {0x01044d, {[CaseLower] = 0x01044d,[CaseTitle] = 0x010425,[CaseUpper] = 0x010425}, NULL},
+ {0x01044e, {[CaseLower] = 0x01044e,[CaseTitle] = 0x010426,[CaseUpper] = 0x010426}, NULL},
+ {0x01044f, {[CaseLower] = 0x01044f,[CaseTitle] = 0x010427,[CaseUpper] = 0x010427}, NULL},
+ {0x0104b0, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104b1, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104b2, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104b3, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104b4, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104b5, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104b6, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104b7, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104b8, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104b9, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104ba, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104bb, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104bc, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104bd, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104be, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104bf, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104c0, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104c1, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104c2, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104c3, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104c4, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104c5, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104c6, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104c7, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104c8, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104c9, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104ca, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104cb, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104cc, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104cd, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104ce, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104cf, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104d0, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104d1, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104d2, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104d3, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x0104d8, {[CaseLower] = 0x0104d8,[CaseTitle] = 0x0104b0,[CaseUpper] = 0x0104b0}, NULL},
+ {0x0104d9, {[CaseLower] = 0x0104d9,[CaseTitle] = 0x0104b1,[CaseUpper] = 0x0104b1}, NULL},
+ {0x0104da, {[CaseLower] = 0x0104da,[CaseTitle] = 0x0104b2,[CaseUpper] = 0x0104b2}, NULL},
+ {0x0104db, {[CaseLower] = 0x0104db,[CaseTitle] = 0x0104b3,[CaseUpper] = 0x0104b3}, NULL},
+ {0x0104dc, {[CaseLower] = 0x0104dc,[CaseTitle] = 0x0104b4,[CaseUpper] = 0x0104b4}, NULL},
+ {0x0104dd, {[CaseLower] = 0x0104dd,[CaseTitle] = 0x0104b5,[CaseUpper] = 0x0104b5}, NULL},
+ {0x0104de, {[CaseLower] = 0x0104de,[CaseTitle] = 0x0104b6,[CaseUpper] = 0x0104b6}, NULL},
+ {0x0104df, {[CaseLower] = 0x0104df,[CaseTitle] = 0x0104b7,[CaseUpper] = 0x0104b7}, NULL},
+ {0x0104e0, {[CaseLower] = 0x0104e0,[CaseTitle] = 0x0104b8,[CaseUpper] = 0x0104b8}, NULL},
+ {0x0104e1, {[CaseLower] = 0x0104e1,[CaseTitle] = 0x0104b9,[CaseUpper] = 0x0104b9}, NULL},
+ {0x0104e2, {[CaseLower] = 0x0104e2,[CaseTitle] = 0x0104ba,[CaseUpper] = 0x0104ba}, NULL},
+ {0x0104e3, {[CaseLower] = 0x0104e3,[CaseTitle] = 0x0104bb,[CaseUpper] = 0x0104bb}, NULL},
+ {0x0104e4, {[CaseLower] = 0x0104e4,[CaseTitle] = 0x0104bc,[CaseUpper] = 0x0104bc}, NULL},
+ {0x0104e5, {[CaseLower] = 0x0104e5,[CaseTitle] = 0x0104bd,[CaseUpper] = 0x0104bd}, NULL},
+ {0x0104e6, {[CaseLower] = 0x0104e6,[CaseTitle] = 0x0104be,[CaseUpper] = 0x0104be}, NULL},
+ {0x0104e7, {[CaseLower] = 0x0104e7,[CaseTitle] = 0x0104bf,[CaseUpper] = 0x0104bf}, NULL},
+ {0x0104e8, {[CaseLower] = 0x0104e8,[CaseTitle] = 0x0104c0,[CaseUpper] = 0x0104c0}, NULL},
+ {0x0104e9, {[CaseLower] = 0x0104e9,[CaseTitle] = 0x0104c1,[CaseUpper] = 0x0104c1}, NULL},
+ {0x0104ea, {[CaseLower] = 0x0104ea,[CaseTitle] = 0x0104c2,[CaseUpper] = 0x0104c2}, NULL},
+ {0x0104eb, {[CaseLower] = 0x0104eb,[CaseTitle] = 0x0104c3,[CaseUpper] = 0x0104c3}, NULL},
+ {0x0104ec, {[CaseLower] = 0x0104ec,[CaseTitle] = 0x0104c4,[CaseUpper] = 0x0104c4}, NULL},
+ {0x0104ed, {[CaseLower] = 0x0104ed,[CaseTitle] = 0x0104c5,[CaseUpper] = 0x0104c5}, NULL},
+ {0x0104ee, {[CaseLower] = 0x0104ee,[CaseTitle] = 0x0104c6,[CaseUpper] = 0x0104c6}, NULL},
+ {0x0104ef, {[CaseLower] = 0x0104ef,[CaseTitle] = 0x0104c7,[CaseUpper] = 0x0104c7}, NULL},
+ {0x0104f0, {[CaseLower] = 0x0104f0,[CaseTitle] = 0x0104c8,[CaseUpper] = 0x0104c8}, NULL},
+ {0x0104f1, {[CaseLower] = 0x0104f1,[CaseTitle] = 0x0104c9,[CaseUpper] = 0x0104c9}, NULL},
+ {0x0104f2, {[CaseLower] = 0x0104f2,[CaseTitle] = 0x0104ca,[CaseUpper] = 0x0104ca}, NULL},
+ {0x0104f3, {[CaseLower] = 0x0104f3,[CaseTitle] = 0x0104cb,[CaseUpper] = 0x0104cb}, NULL},
+ {0x0104f4, {[CaseLower] = 0x0104f4,[CaseTitle] = 0x0104cc,[CaseUpper] = 0x0104cc}, NULL},
+ {0x0104f5, {[CaseLower] = 0x0104f5,[CaseTitle] = 0x0104cd,[CaseUpper] = 0x0104cd}, NULL},
+ {0x0104f6, {[CaseLower] = 0x0104f6,[CaseTitle] = 0x0104ce,[CaseUpper] = 0x0104ce}, NULL},
+ {0x0104f7, {[CaseLower] = 0x0104f7,[CaseTitle] = 0x0104cf,[CaseUpper] = 0x0104cf}, NULL},
+ {0x0104f8, {[CaseLower] = 0x0104f8,[CaseTitle] = 0x0104d0,[CaseUpper] = 0x0104d0}, NULL},
+ {0x0104f9, {[CaseLower] = 0x0104f9,[CaseTitle] = 0x0104d1,[CaseUpper] = 0x0104d1}, NULL},
+ {0x0104fa, {[CaseLower] = 0x0104fa,[CaseTitle] = 0x0104d2,[CaseUpper] = 0x0104d2}, NULL},
+ {0x0104fb, {[CaseLower] = 0x0104fb,[CaseTitle] = 0x0104d3,[CaseUpper] = 0x0104d3}, NULL},
+ {0x010570, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010571, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010572, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x010573, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x010574, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x010575, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x010576, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x010577, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x010578, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x010579, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x01057a, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x01057c, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x01057d, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x01057e, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x01057f, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x010580, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x010581, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x010582, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x010583, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x010584, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x010585, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x010586, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x010587, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x010588, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x010589, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x01058a, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x01058c, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x01058d, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x01058e, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x01058f, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x010590, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x010591, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x010592, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x010594, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x010595, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010597, {[CaseLower] = 0x010597,[CaseTitle] = 0x010570,[CaseUpper] = 0x010570}, NULL},
+ {0x010598, {[CaseLower] = 0x010598,[CaseTitle] = 0x010571,[CaseUpper] = 0x010571}, NULL},
+ {0x010599, {[CaseLower] = 0x010599,[CaseTitle] = 0x010572,[CaseUpper] = 0x010572}, NULL},
+ {0x01059a, {[CaseLower] = 0x01059a,[CaseTitle] = 0x010573,[CaseUpper] = 0x010573}, NULL},
+ {0x01059b, {[CaseLower] = 0x01059b,[CaseTitle] = 0x010574,[CaseUpper] = 0x010574}, NULL},
+ {0x01059c, {[CaseLower] = 0x01059c,[CaseTitle] = 0x010575,[CaseUpper] = 0x010575}, NULL},
+ {0x01059d, {[CaseLower] = 0x01059d,[CaseTitle] = 0x010576,[CaseUpper] = 0x010576}, NULL},
+ {0x01059e, {[CaseLower] = 0x01059e,[CaseTitle] = 0x010577,[CaseUpper] = 0x010577}, NULL},
+ {0x01059f, {[CaseLower] = 0x01059f,[CaseTitle] = 0x010578,[CaseUpper] = 0x010578}, NULL},
+ {0x0105a0, {[CaseLower] = 0x0105a0,[CaseTitle] = 0x010579,[CaseUpper] = 0x010579}, NULL},
+ {0x0105a1, {[CaseLower] = 0x0105a1,[CaseTitle] = 0x01057a,[CaseUpper] = 0x01057a}, NULL},
+ {0x0105a3, {[CaseLower] = 0x0105a3,[CaseTitle] = 0x01057c,[CaseUpper] = 0x01057c}, NULL},
+ {0x0105a4, {[CaseLower] = 0x0105a4,[CaseTitle] = 0x01057d,[CaseUpper] = 0x01057d}, NULL},
+ {0x0105a5, {[CaseLower] = 0x0105a5,[CaseTitle] = 0x01057e,[CaseUpper] = 0x01057e}, NULL},
+ {0x0105a6, {[CaseLower] = 0x0105a6,[CaseTitle] = 0x01057f,[CaseUpper] = 0x01057f}, NULL},
+ {0x0105a7, {[CaseLower] = 0x0105a7,[CaseTitle] = 0x010580,[CaseUpper] = 0x010580}, NULL},
+ {0x0105a8, {[CaseLower] = 0x0105a8,[CaseTitle] = 0x010581,[CaseUpper] = 0x010581}, NULL},
+ {0x0105a9, {[CaseLower] = 0x0105a9,[CaseTitle] = 0x010582,[CaseUpper] = 0x010582}, NULL},
+ {0x0105aa, {[CaseLower] = 0x0105aa,[CaseTitle] = 0x010583,[CaseUpper] = 0x010583}, NULL},
+ {0x0105ab, {[CaseLower] = 0x0105ab,[CaseTitle] = 0x010584,[CaseUpper] = 0x010584}, NULL},
+ {0x0105ac, {[CaseLower] = 0x0105ac,[CaseTitle] = 0x010585,[CaseUpper] = 0x010585}, NULL},
+ {0x0105ad, {[CaseLower] = 0x0105ad,[CaseTitle] = 0x010586,[CaseUpper] = 0x010586}, NULL},
+ {0x0105ae, {[CaseLower] = 0x0105ae,[CaseTitle] = 0x010587,[CaseUpper] = 0x010587}, NULL},
+ {0x0105af, {[CaseLower] = 0x0105af,[CaseTitle] = 0x010588,[CaseUpper] = 0x010588}, NULL},
+ {0x0105b0, {[CaseLower] = 0x0105b0,[CaseTitle] = 0x010589,[CaseUpper] = 0x010589}, NULL},
+ {0x0105b1, {[CaseLower] = 0x0105b1,[CaseTitle] = 0x01058a,[CaseUpper] = 0x01058a}, NULL},
+ {0x0105b3, {[CaseLower] = 0x0105b3,[CaseTitle] = 0x01058c,[CaseUpper] = 0x01058c}, NULL},
+ {0x0105b4, {[CaseLower] = 0x0105b4,[CaseTitle] = 0x01058d,[CaseUpper] = 0x01058d}, NULL},
+ {0x0105b5, {[CaseLower] = 0x0105b5,[CaseTitle] = 0x01058e,[CaseUpper] = 0x01058e}, NULL},
+ {0x0105b6, {[CaseLower] = 0x0105b6,[CaseTitle] = 0x01058f,[CaseUpper] = 0x01058f}, NULL},
+ {0x0105b7, {[CaseLower] = 0x0105b7,[CaseTitle] = 0x010590,[CaseUpper] = 0x010590}, NULL},
+ {0x0105b8, {[CaseLower] = 0x0105b8,[CaseTitle] = 0x010591,[CaseUpper] = 0x010591}, NULL},
+ {0x0105b9, {[CaseLower] = 0x0105b9,[CaseTitle] = 0x010592,[CaseUpper] = 0x010592}, NULL},
+ {0x0105bb, {[CaseLower] = 0x0105bb,[CaseTitle] = 0x010594,[CaseUpper] = 0x010594}, NULL},
+ {0x0105bc, {[CaseLower] = 0x0105bc,[CaseTitle] = 0x010595,[CaseUpper] = 0x010595}, NULL},
+ {0x010c80, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010c81, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010c82, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010c83, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010c84, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010c85, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010c86, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010c87, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010c88, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010c89, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010c8a, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010c8b, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010c8c, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010c8d, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010c8e, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010c8f, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010c90, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010c91, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010c92, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010c93, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010c94, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010c95, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010c96, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010c97, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010c98, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010c99, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010c9a, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010c9b, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010c9c, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010c9d, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010c9e, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010c9f, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ca0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ca1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ca2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ca3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ca4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ca5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ca6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ca7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ca8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ca9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010caa, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010cab, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cac, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010cad, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cae, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010caf, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cb0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cb1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cb2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x010cc0, {[CaseLower] = 0x010cc0,[CaseTitle] = 0x010c80,[CaseUpper] = 0x010c80}, NULL},
+ {0x010cc1, {[CaseLower] = 0x010cc1,[CaseTitle] = 0x010c81,[CaseUpper] = 0x010c81}, NULL},
+ {0x010cc2, {[CaseLower] = 0x010cc2,[CaseTitle] = 0x010c82,[CaseUpper] = 0x010c82}, NULL},
+ {0x010cc3, {[CaseLower] = 0x010cc3,[CaseTitle] = 0x010c83,[CaseUpper] = 0x010c83}, NULL},
+ {0x010cc4, {[CaseLower] = 0x010cc4,[CaseTitle] = 0x010c84,[CaseUpper] = 0x010c84}, NULL},
+ {0x010cc5, {[CaseLower] = 0x010cc5,[CaseTitle] = 0x010c85,[CaseUpper] = 0x010c85}, NULL},
+ {0x010cc6, {[CaseLower] = 0x010cc6,[CaseTitle] = 0x010c86,[CaseUpper] = 0x010c86}, NULL},
+ {0x010cc7, {[CaseLower] = 0x010cc7,[CaseTitle] = 0x010c87,[CaseUpper] = 0x010c87}, NULL},
+ {0x010cc8, {[CaseLower] = 0x010cc8,[CaseTitle] = 0x010c88,[CaseUpper] = 0x010c88}, NULL},
+ {0x010cc9, {[CaseLower] = 0x010cc9,[CaseTitle] = 0x010c89,[CaseUpper] = 0x010c89}, NULL},
+ {0x010cca, {[CaseLower] = 0x010cca,[CaseTitle] = 0x010c8a,[CaseUpper] = 0x010c8a}, NULL},
+ {0x010ccb, {[CaseLower] = 0x010ccb,[CaseTitle] = 0x010c8b,[CaseUpper] = 0x010c8b}, NULL},
+ {0x010ccc, {[CaseLower] = 0x010ccc,[CaseTitle] = 0x010c8c,[CaseUpper] = 0x010c8c}, NULL},
+ {0x010ccd, {[CaseLower] = 0x010ccd,[CaseTitle] = 0x010c8d,[CaseUpper] = 0x010c8d}, NULL},
+ {0x010cce, {[CaseLower] = 0x010cce,[CaseTitle] = 0x010c8e,[CaseUpper] = 0x010c8e}, NULL},
+ {0x010ccf, {[CaseLower] = 0x010ccf,[CaseTitle] = 0x010c8f,[CaseUpper] = 0x010c8f}, NULL},
+ {0x010cd0, {[CaseLower] = 0x010cd0,[CaseTitle] = 0x010c90,[CaseUpper] = 0x010c90}, NULL},
+ {0x010cd1, {[CaseLower] = 0x010cd1,[CaseTitle] = 0x010c91,[CaseUpper] = 0x010c91}, NULL},
+ {0x010cd2, {[CaseLower] = 0x010cd2,[CaseTitle] = 0x010c92,[CaseUpper] = 0x010c92}, NULL},
+ {0x010cd3, {[CaseLower] = 0x010cd3,[CaseTitle] = 0x010c93,[CaseUpper] = 0x010c93}, NULL},
+ {0x010cd4, {[CaseLower] = 0x010cd4,[CaseTitle] = 0x010c94,[CaseUpper] = 0x010c94}, NULL},
+ {0x010cd5, {[CaseLower] = 0x010cd5,[CaseTitle] = 0x010c95,[CaseUpper] = 0x010c95}, NULL},
+ {0x010cd6, {[CaseLower] = 0x010cd6,[CaseTitle] = 0x010c96,[CaseUpper] = 0x010c96}, NULL},
+ {0x010cd7, {[CaseLower] = 0x010cd7,[CaseTitle] = 0x010c97,[CaseUpper] = 0x010c97}, NULL},
+ {0x010cd8, {[CaseLower] = 0x010cd8,[CaseTitle] = 0x010c98,[CaseUpper] = 0x010c98}, NULL},
+ {0x010cd9, {[CaseLower] = 0x010cd9,[CaseTitle] = 0x010c99,[CaseUpper] = 0x010c99}, NULL},
+ {0x010cda, {[CaseLower] = 0x010cda,[CaseTitle] = 0x010c9a,[CaseUpper] = 0x010c9a}, NULL},
+ {0x010cdb, {[CaseLower] = 0x010cdb,[CaseTitle] = 0x010c9b,[CaseUpper] = 0x010c9b}, NULL},
+ {0x010cdc, {[CaseLower] = 0x010cdc,[CaseTitle] = 0x010c9c,[CaseUpper] = 0x010c9c}, NULL},
+ {0x010cdd, {[CaseLower] = 0x010cdd,[CaseTitle] = 0x010c9d,[CaseUpper] = 0x010c9d}, NULL},
+ {0x010cde, {[CaseLower] = 0x010cde,[CaseTitle] = 0x010c9e,[CaseUpper] = 0x010c9e}, NULL},
+ {0x010cdf, {[CaseLower] = 0x010cdf,[CaseTitle] = 0x010c9f,[CaseUpper] = 0x010c9f}, NULL},
+ {0x010ce0, {[CaseLower] = 0x010ce0,[CaseTitle] = 0x010ca0,[CaseUpper] = 0x010ca0}, NULL},
+ {0x010ce1, {[CaseLower] = 0x010ce1,[CaseTitle] = 0x010ca1,[CaseUpper] = 0x010ca1}, NULL},
+ {0x010ce2, {[CaseLower] = 0x010ce2,[CaseTitle] = 0x010ca2,[CaseUpper] = 0x010ca2}, NULL},
+ {0x010ce3, {[CaseLower] = 0x010ce3,[CaseTitle] = 0x010ca3,[CaseUpper] = 0x010ca3}, NULL},
+ {0x010ce4, {[CaseLower] = 0x010ce4,[CaseTitle] = 0x010ca4,[CaseUpper] = 0x010ca4}, NULL},
+ {0x010ce5, {[CaseLower] = 0x010ce5,[CaseTitle] = 0x010ca5,[CaseUpper] = 0x010ca5}, NULL},
+ {0x010ce6, {[CaseLower] = 0x010ce6,[CaseTitle] = 0x010ca6,[CaseUpper] = 0x010ca6}, NULL},
+ {0x010ce7, {[CaseLower] = 0x010ce7,[CaseTitle] = 0x010ca7,[CaseUpper] = 0x010ca7}, NULL},
+ {0x010ce8, {[CaseLower] = 0x010ce8,[CaseTitle] = 0x010ca8,[CaseUpper] = 0x010ca8}, NULL},
+ {0x010ce9, {[CaseLower] = 0x010ce9,[CaseTitle] = 0x010ca9,[CaseUpper] = 0x010ca9}, NULL},
+ {0x010cea, {[CaseLower] = 0x010cea,[CaseTitle] = 0x010caa,[CaseUpper] = 0x010caa}, NULL},
+ {0x010ceb, {[CaseLower] = 0x010ceb,[CaseTitle] = 0x010cab,[CaseUpper] = 0x010cab}, NULL},
+ {0x010cec, {[CaseLower] = 0x010cec,[CaseTitle] = 0x010cac,[CaseUpper] = 0x010cac}, NULL},
+ {0x010ced, {[CaseLower] = 0x010ced,[CaseTitle] = 0x010cad,[CaseUpper] = 0x010cad}, NULL},
+ {0x010cee, {[CaseLower] = 0x010cee,[CaseTitle] = 0x010cae,[CaseUpper] = 0x010cae}, NULL},
+ {0x010cef, {[CaseLower] = 0x010cef,[CaseTitle] = 0x010caf,[CaseUpper] = 0x010caf}, NULL},
+ {0x010cf0, {[CaseLower] = 0x010cf0,[CaseTitle] = 0x010cb0,[CaseUpper] = 0x010cb0}, NULL},
+ {0x010cf1, {[CaseLower] = 0x010cf1,[CaseTitle] = 0x010cb1,[CaseUpper] = 0x010cb1}, NULL},
+ {0x010cf2, {[CaseLower] = 0x010cf2,[CaseTitle] = 0x010cb2,[CaseUpper] = 0x010cb2}, NULL},
+ {0x0118a0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118a1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118a2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118a3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118a4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118a5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118a6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118a7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118a8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118a9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118aa, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118ab, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118ac, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118ad, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ae, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118af, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118b0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118b1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118b2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118b3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118b4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118b5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118b6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118b7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118b8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118b9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118ba, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118bb, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118bc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118bd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118be, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118bf, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x0118c0, {[CaseLower] = 0x0118c0,[CaseTitle] = 0x0118a0,[CaseUpper] = 0x0118a0}, NULL},
+ {0x0118c1, {[CaseLower] = 0x0118c1,[CaseTitle] = 0x0118a1,[CaseUpper] = 0x0118a1}, NULL},
+ {0x0118c2, {[CaseLower] = 0x0118c2,[CaseTitle] = 0x0118a2,[CaseUpper] = 0x0118a2}, NULL},
+ {0x0118c3, {[CaseLower] = 0x0118c3,[CaseTitle] = 0x0118a3,[CaseUpper] = 0x0118a3}, NULL},
+ {0x0118c4, {[CaseLower] = 0x0118c4,[CaseTitle] = 0x0118a4,[CaseUpper] = 0x0118a4}, NULL},
+ {0x0118c5, {[CaseLower] = 0x0118c5,[CaseTitle] = 0x0118a5,[CaseUpper] = 0x0118a5}, NULL},
+ {0x0118c6, {[CaseLower] = 0x0118c6,[CaseTitle] = 0x0118a6,[CaseUpper] = 0x0118a6}, NULL},
+ {0x0118c7, {[CaseLower] = 0x0118c7,[CaseTitle] = 0x0118a7,[CaseUpper] = 0x0118a7}, NULL},
+ {0x0118c8, {[CaseLower] = 0x0118c8,[CaseTitle] = 0x0118a8,[CaseUpper] = 0x0118a8}, NULL},
+ {0x0118c9, {[CaseLower] = 0x0118c9,[CaseTitle] = 0x0118a9,[CaseUpper] = 0x0118a9}, NULL},
+ {0x0118ca, {[CaseLower] = 0x0118ca,[CaseTitle] = 0x0118aa,[CaseUpper] = 0x0118aa}, NULL},
+ {0x0118cb, {[CaseLower] = 0x0118cb,[CaseTitle] = 0x0118ab,[CaseUpper] = 0x0118ab}, NULL},
+ {0x0118cc, {[CaseLower] = 0x0118cc,[CaseTitle] = 0x0118ac,[CaseUpper] = 0x0118ac}, NULL},
+ {0x0118cd, {[CaseLower] = 0x0118cd,[CaseTitle] = 0x0118ad,[CaseUpper] = 0x0118ad}, NULL},
+ {0x0118ce, {[CaseLower] = 0x0118ce,[CaseTitle] = 0x0118ae,[CaseUpper] = 0x0118ae}, NULL},
+ {0x0118cf, {[CaseLower] = 0x0118cf,[CaseTitle] = 0x0118af,[CaseUpper] = 0x0118af}, NULL},
+ {0x0118d0, {[CaseLower] = 0x0118d0,[CaseTitle] = 0x0118b0,[CaseUpper] = 0x0118b0}, NULL},
+ {0x0118d1, {[CaseLower] = 0x0118d1,[CaseTitle] = 0x0118b1,[CaseUpper] = 0x0118b1}, NULL},
+ {0x0118d2, {[CaseLower] = 0x0118d2,[CaseTitle] = 0x0118b2,[CaseUpper] = 0x0118b2}, NULL},
+ {0x0118d3, {[CaseLower] = 0x0118d3,[CaseTitle] = 0x0118b3,[CaseUpper] = 0x0118b3}, NULL},
+ {0x0118d4, {[CaseLower] = 0x0118d4,[CaseTitle] = 0x0118b4,[CaseUpper] = 0x0118b4}, NULL},
+ {0x0118d5, {[CaseLower] = 0x0118d5,[CaseTitle] = 0x0118b5,[CaseUpper] = 0x0118b5}, NULL},
+ {0x0118d6, {[CaseLower] = 0x0118d6,[CaseTitle] = 0x0118b6,[CaseUpper] = 0x0118b6}, NULL},
+ {0x0118d7, {[CaseLower] = 0x0118d7,[CaseTitle] = 0x0118b7,[CaseUpper] = 0x0118b7}, NULL},
+ {0x0118d8, {[CaseLower] = 0x0118d8,[CaseTitle] = 0x0118b8,[CaseUpper] = 0x0118b8}, NULL},
+ {0x0118d9, {[CaseLower] = 0x0118d9,[CaseTitle] = 0x0118b9,[CaseUpper] = 0x0118b9}, NULL},
+ {0x0118da, {[CaseLower] = 0x0118da,[CaseTitle] = 0x0118ba,[CaseUpper] = 0x0118ba}, NULL},
+ {0x0118db, {[CaseLower] = 0x0118db,[CaseTitle] = 0x0118bb,[CaseUpper] = 0x0118bb}, NULL},
+ {0x0118dc, {[CaseLower] = 0x0118dc,[CaseTitle] = 0x0118bc,[CaseUpper] = 0x0118bc}, NULL},
+ {0x0118dd, {[CaseLower] = 0x0118dd,[CaseTitle] = 0x0118bd,[CaseUpper] = 0x0118bd}, NULL},
+ {0x0118de, {[CaseLower] = 0x0118de,[CaseTitle] = 0x0118be,[CaseUpper] = 0x0118be}, NULL},
+ {0x0118df, {[CaseLower] = 0x0118df,[CaseTitle] = 0x0118bf,[CaseUpper] = 0x0118bf}, NULL},
+ {0x016e40, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e41, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e42, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e43, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e44, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e45, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e46, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e47, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e48, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e49, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e4a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e4b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e4c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e4d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e4e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e4f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e50, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e51, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e52, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e53, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e54, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e55, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e56, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e57, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e58, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e59, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e5a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e5b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e5c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e5d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e5e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e5f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x016e60, {[CaseLower] = 0x016e60,[CaseTitle] = 0x016e40,[CaseUpper] = 0x016e40}, NULL},
+ {0x016e61, {[CaseLower] = 0x016e61,[CaseTitle] = 0x016e41,[CaseUpper] = 0x016e41}, NULL},
+ {0x016e62, {[CaseLower] = 0x016e62,[CaseTitle] = 0x016e42,[CaseUpper] = 0x016e42}, NULL},
+ {0x016e63, {[CaseLower] = 0x016e63,[CaseTitle] = 0x016e43,[CaseUpper] = 0x016e43}, NULL},
+ {0x016e64, {[CaseLower] = 0x016e64,[CaseTitle] = 0x016e44,[CaseUpper] = 0x016e44}, NULL},
+ {0x016e65, {[CaseLower] = 0x016e65,[CaseTitle] = 0x016e45,[CaseUpper] = 0x016e45}, NULL},
+ {0x016e66, {[CaseLower] = 0x016e66,[CaseTitle] = 0x016e46,[CaseUpper] = 0x016e46}, NULL},
+ {0x016e67, {[CaseLower] = 0x016e67,[CaseTitle] = 0x016e47,[CaseUpper] = 0x016e47}, NULL},
+ {0x016e68, {[CaseLower] = 0x016e68,[CaseTitle] = 0x016e48,[CaseUpper] = 0x016e48}, NULL},
+ {0x016e69, {[CaseLower] = 0x016e69,[CaseTitle] = 0x016e49,[CaseUpper] = 0x016e49}, NULL},
+ {0x016e6a, {[CaseLower] = 0x016e6a,[CaseTitle] = 0x016e4a,[CaseUpper] = 0x016e4a}, NULL},
+ {0x016e6b, {[CaseLower] = 0x016e6b,[CaseTitle] = 0x016e4b,[CaseUpper] = 0x016e4b}, NULL},
+ {0x016e6c, {[CaseLower] = 0x016e6c,[CaseTitle] = 0x016e4c,[CaseUpper] = 0x016e4c}, NULL},
+ {0x016e6d, {[CaseLower] = 0x016e6d,[CaseTitle] = 0x016e4d,[CaseUpper] = 0x016e4d}, NULL},
+ {0x016e6e, {[CaseLower] = 0x016e6e,[CaseTitle] = 0x016e4e,[CaseUpper] = 0x016e4e}, NULL},
+ {0x016e6f, {[CaseLower] = 0x016e6f,[CaseTitle] = 0x016e4f,[CaseUpper] = 0x016e4f}, NULL},
+ {0x016e70, {[CaseLower] = 0x016e70,[CaseTitle] = 0x016e50,[CaseUpper] = 0x016e50}, NULL},
+ {0x016e71, {[CaseLower] = 0x016e71,[CaseTitle] = 0x016e51,[CaseUpper] = 0x016e51}, NULL},
+ {0x016e72, {[CaseLower] = 0x016e72,[CaseTitle] = 0x016e52,[CaseUpper] = 0x016e52}, NULL},
+ {0x016e73, {[CaseLower] = 0x016e73,[CaseTitle] = 0x016e53,[CaseUpper] = 0x016e53}, NULL},
+ {0x016e74, {[CaseLower] = 0x016e74,[CaseTitle] = 0x016e54,[CaseUpper] = 0x016e54}, NULL},
+ {0x016e75, {[CaseLower] = 0x016e75,[CaseTitle] = 0x016e55,[CaseUpper] = 0x016e55}, NULL},
+ {0x016e76, {[CaseLower] = 0x016e76,[CaseTitle] = 0x016e56,[CaseUpper] = 0x016e56}, NULL},
+ {0x016e77, {[CaseLower] = 0x016e77,[CaseTitle] = 0x016e57,[CaseUpper] = 0x016e57}, NULL},
+ {0x016e78, {[CaseLower] = 0x016e78,[CaseTitle] = 0x016e58,[CaseUpper] = 0x016e58}, NULL},
+ {0x016e79, {[CaseLower] = 0x016e79,[CaseTitle] = 0x016e59,[CaseUpper] = 0x016e59}, NULL},
+ {0x016e7a, {[CaseLower] = 0x016e7a,[CaseTitle] = 0x016e5a,[CaseUpper] = 0x016e5a}, NULL},
+ {0x016e7b, {[CaseLower] = 0x016e7b,[CaseTitle] = 0x016e5b,[CaseUpper] = 0x016e5b}, NULL},
+ {0x016e7c, {[CaseLower] = 0x016e7c,[CaseTitle] = 0x016e5c,[CaseUpper] = 0x016e5c}, NULL},
+ {0x016e7d, {[CaseLower] = 0x016e7d,[CaseTitle] = 0x016e5d,[CaseUpper] = 0x016e5d}, NULL},
+ {0x016e7e, {[CaseLower] = 0x016e7e,[CaseTitle] = 0x016e5e,[CaseUpper] = 0x016e5e}, NULL},
+ {0x016e7f, {[CaseLower] = 0x016e7f,[CaseTitle] = 0x016e5f,[CaseUpper] = 0x016e5f}, NULL},
+ {0x01e900, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e901, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e902, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e903, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e904, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e905, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e906, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e907, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e908, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e909, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e90a, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e90b, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e90c, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e90d, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e90e, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e90f, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e910, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e911, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e912, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e913, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e914, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e915, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e916, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e917, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e918, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e919, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e91a, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e91b, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e91c, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e91d, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e91e, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e91f, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e920, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e921, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
+ {0x01e922, {[CaseLower] = 0x01e922,[CaseTitle] = 0x01e900,[CaseUpper] = 0x01e900}, NULL},
+ {0x01e923, {[CaseLower] = 0x01e923,[CaseTitle] = 0x01e901,[CaseUpper] = 0x01e901}, NULL},
+ {0x01e924, {[CaseLower] = 0x01e924,[CaseTitle] = 0x01e902,[CaseUpper] = 0x01e902}, NULL},
+ {0x01e925, {[CaseLower] = 0x01e925,[CaseTitle] = 0x01e903,[CaseUpper] = 0x01e903}, NULL},
+ {0x01e926, {[CaseLower] = 0x01e926,[CaseTitle] = 0x01e904,[CaseUpper] = 0x01e904}, NULL},
+ {0x01e927, {[CaseLower] = 0x01e927,[CaseTitle] = 0x01e905,[CaseUpper] = 0x01e905}, NULL},
+ {0x01e928, {[CaseLower] = 0x01e928,[CaseTitle] = 0x01e906,[CaseUpper] = 0x01e906}, NULL},
+ {0x01e929, {[CaseLower] = 0x01e929,[CaseTitle] = 0x01e907,[CaseUpper] = 0x01e907}, NULL},
+ {0x01e92a, {[CaseLower] = 0x01e92a,[CaseTitle] = 0x01e908,[CaseUpper] = 0x01e908}, NULL},
+ {0x01e92b, {[CaseLower] = 0x01e92b,[CaseTitle] = 0x01e909,[CaseUpper] = 0x01e909}, NULL},
+ {0x01e92c, {[CaseLower] = 0x01e92c,[CaseTitle] = 0x01e90a,[CaseUpper] = 0x01e90a}, NULL},
+ {0x01e92d, {[CaseLower] = 0x01e92d,[CaseTitle] = 0x01e90b,[CaseUpper] = 0x01e90b}, NULL},
+ {0x01e92e, {[CaseLower] = 0x01e92e,[CaseTitle] = 0x01e90c,[CaseUpper] = 0x01e90c}, NULL},
+ {0x01e92f, {[CaseLower] = 0x01e92f,[CaseTitle] = 0x01e90d,[CaseUpper] = 0x01e90d}, NULL},
+ {0x01e930, {[CaseLower] = 0x01e930,[CaseTitle] = 0x01e90e,[CaseUpper] = 0x01e90e}, NULL},
+ {0x01e931, {[CaseLower] = 0x01e931,[CaseTitle] = 0x01e90f,[CaseUpper] = 0x01e90f}, NULL},
+ {0x01e932, {[CaseLower] = 0x01e932,[CaseTitle] = 0x01e910,[CaseUpper] = 0x01e910}, NULL},
+ {0x01e933, {[CaseLower] = 0x01e933,[CaseTitle] = 0x01e911,[CaseUpper] = 0x01e911}, NULL},
+ {0x01e934, {[CaseLower] = 0x01e934,[CaseTitle] = 0x01e912,[CaseUpper] = 0x01e912}, NULL},
+ {0x01e935, {[CaseLower] = 0x01e935,[CaseTitle] = 0x01e913,[CaseUpper] = 0x01e913}, NULL},
+ {0x01e936, {[CaseLower] = 0x01e936,[CaseTitle] = 0x01e914,[CaseUpper] = 0x01e914}, NULL},
+ {0x01e937, {[CaseLower] = 0x01e937,[CaseTitle] = 0x01e915,[CaseUpper] = 0x01e915}, NULL},
+ {0x01e938, {[CaseLower] = 0x01e938,[CaseTitle] = 0x01e916,[CaseUpper] = 0x01e916}, NULL},
+ {0x01e939, {[CaseLower] = 0x01e939,[CaseTitle] = 0x01e917,[CaseUpper] = 0x01e917}, NULL},
+ {0x01e93a, {[CaseLower] = 0x01e93a,[CaseTitle] = 0x01e918,[CaseUpper] = 0x01e918}, NULL},
+ {0x01e93b, {[CaseLower] = 0x01e93b,[CaseTitle] = 0x01e919,[CaseUpper] = 0x01e919}, NULL},
+ {0x01e93c, {[CaseLower] = 0x01e93c,[CaseTitle] = 0x01e91a,[CaseUpper] = 0x01e91a}, NULL},
+ {0x01e93d, {[CaseLower] = 0x01e93d,[CaseTitle] = 0x01e91b,[CaseUpper] = 0x01e91b}, NULL},
+ {0x01e93e, {[CaseLower] = 0x01e93e,[CaseTitle] = 0x01e91c,[CaseUpper] = 0x01e91c}, NULL},
+ {0x01e93f, {[CaseLower] = 0x01e93f,[CaseTitle] = 0x01e91d,[CaseUpper] = 0x01e91d}, NULL},
+ {0x01e940, {[CaseLower] = 0x01e940,[CaseTitle] = 0x01e91e,[CaseUpper] = 0x01e91e}, NULL},
+ {0x01e941, {[CaseLower] = 0x01e941,[CaseTitle] = 0x01e91f,[CaseUpper] = 0x01e91f}, NULL},
+ {0x01e942, {[CaseLower] = 0x01e942,[CaseTitle] = 0x01e920,[CaseUpper] = 0x01e920}, NULL},
+ {0x01e943, {[CaseLower] = 0x01e943,[CaseTitle] = 0x01e921,[CaseUpper] = 0x01e921}, NULL},
};
--
2.34.1
[text/x-patch] v28-0002-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch (21.4K, ../../[email protected]/3-v28-0002-Support-PG_UNICODE_FAST-locale-in-the-builtin-co.patch)
download | inline diff:
From d4c92a7f9e804f228c9d92881003305e68ebab69 Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 6 Mar 2024 18:15:33 -0800
Subject: [PATCH v28 2/2] Support PG_UNICODE_FAST locale in the builtin
collation provider.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------ CATVERSION ------
The PG_UNICODE_FAST locale uses code point sort order (fast,
memcmp-based) combined with Unicode character semantics. The character
semantics are based on Unicode full case mapping.
Full case mapping can map a single codepoint to multiple codepoints,
such as "ß" uppercasing to "SS". Additionally, it handles
context-sensitive mappings like the "final sigma", and it uses
titlecase mappings such as "Dž" when titlecasing (rather than plain
uppercase mappings).
Importantly, the uppercasing of "ß" as "SS" is specifically mentioned
by the SQL standard. In Postgres, UCS_BASIC uses plain ASCII semantics
for case mapping and pattern matching, so if we changed it to use the
PG_UNICODE_FAST locale, it would offer better compliance with the
standard. For now, though, do not change the behavior of UCS_BASIC.
Discussion: https://postgr.es/m/[email protected]
---
doc/src/sgml/charset.sgml | 17 +++
doc/src/sgml/ref/create_collation.sgml | 3 +-
doc/src/sgml/ref/create_database.sgml | 6 +-
doc/src/sgml/ref/initdb.sgml | 4 +-
src/backend/regex/regc_pg_locale.c | 11 +-
src/backend/utils/adt/formatting.c | 22 ++-
src/backend/utils/adt/pg_locale.c | 10 +-
src/backend/utils/init/postinit.c | 1 +
src/bin/initdb/initdb.c | 6 +-
src/include/catalog/pg_collation.dat | 3 +
src/include/utils/pg_locale.h | 1 +
src/test/regress/expected/collate.utf8.out | 160 +++++++++++++++++++++
src/test/regress/sql/collate.utf8.sql | 60 ++++++++
13 files changed, 287 insertions(+), 17 deletions(-)
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
index 55bbb20dac..fc520138a6 100644
--- a/doc/src/sgml/charset.sgml
+++ b/doc/src/sgml/charset.sgml
@@ -886,6 +886,23 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>pg_unicode_fast</literal></term>
+ <listitem>
+ <para>
+ This collation sorts by Unicode code point values rather than natural
+ language order. For the functions <function>lower</function>,
+ <function>initcap</function>, and <function>upper</function> it uses
+ Unicode full case mapping. For pattern matching (including regular
+ expressions), it uses the Standard variant of Unicode <ulink
+ url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
+ Properties</ulink>. Behavior is efficient and stable within a
+ <productname>Postgres</productname> major version. It is only
+ available for encoding <literal>UTF8</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>pg_c_utf8</literal></term>
<listitem>
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index 85f18cbbe5..4c03e25d02 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -99,7 +99,8 @@ CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replace
<para>
If <replaceable>provider</replaceable> is <literal>builtin</literal>,
then <replaceable>locale</replaceable> must be specified and set to
- either <literal>C</literal> or <literal>C.UTF-8</literal>.
+ either <literal>C</literal>, <literal>C.UTF-8</literal> or
+ <literal>PG_UNICODE_FAST</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
index 7653cb902e..a4b052ba08 100644
--- a/doc/src/sgml/ref/create_database.sgml
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -168,7 +168,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
If <xref linkend="create-database-locale-provider"/> is
<literal>builtin</literal>, then <replaceable>locale</replaceable> or
<replaceable>builtin_locale</replaceable> must be specified and set to
- either <literal>C</literal> or <literal>C.UTF-8</literal>.
+ either <literal>C</literal>, <literal>C.UTF-8</literal>, or
+ <literal>PG_UNICODE_FAST</literal>.
</para>
<tip>
<para>
@@ -233,7 +234,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
</para>
<para>
The locales available for the <literal>builtin</literal> provider are
- <literal>C</literal> and <literal>C.UTF-8</literal>.
+ <literal>C</literal>, <literal>C.UTF-8</literal> and
+ <literal>PG_UNICODE_FAST</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index dc9011b40e..dd15de82f6 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -289,8 +289,8 @@ PostgreSQL documentation
<para>
If <option>--locale-provider</option> is <literal>builtin</literal>,
<option>--locale</option> or <option>--builtin-locale</option> must be
- specified and set to <literal>C</literal> or
- <literal>C.UTF-8</literal>.
+ specified and set to <literal>C</literal>, <literal>C.UTF-8</literal>
+ or <literal>PG_UNICODE_FAST</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c
index 85f3238eb0..24c5200cef 100644
--- a/src/backend/regex/regc_pg_locale.c
+++ b/src/backend/regex/regc_pg_locale.c
@@ -78,6 +78,8 @@ static PG_Locale_Strategy pg_regex_strategy;
static pg_locale_t pg_regex_locale;
static Oid pg_regex_collation;
+static bool regex_builtin_cclass_posix = false;
+
/*
* Hard-wired character properties for C locale
*/
@@ -271,7 +273,10 @@ pg_set_regex_collation(Oid collation)
if (pg_regex_locale)
{
if (pg_regex_locale->provider == COLLPROVIDER_BUILTIN)
+ {
pg_regex_strategy = PG_REGEX_BUILTIN;
+ regex_builtin_cclass_posix = !pg_regex_locale->info.builtin.casemap_full;
+ }
else
pg_regex_strategy = PG_REGEX_LOCALE_WIDE_L;
}
@@ -299,7 +304,7 @@ pg_wc_isdigit(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISDIGIT));
case PG_REGEX_BUILTIN:
- return pg_u_isdigit(c, true);
+ return pg_u_isdigit(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswdigit((wint_t) c);
@@ -367,7 +372,7 @@ pg_wc_isalnum(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISALNUM));
case PG_REGEX_BUILTIN:
- return pg_u_isalnum(c, true);
+ return pg_u_isalnum(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswalnum((wint_t) c);
@@ -546,7 +551,7 @@ pg_wc_ispunct(pg_wchar c)
return (c <= (pg_wchar) 127 &&
(pg_char_properties[c] & PG_ISPUNCT));
case PG_REGEX_BUILTIN:
- return pg_u_ispunct(c, true);
+ return pg_u_ispunct(c, regex_builtin_cclass_posix);
case PG_REGEX_LOCALE_WIDE:
if (sizeof(wchar_t) >= 4 || c <= (pg_wchar) 0xFFFF)
return iswpunct((wint_t) c);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index c2acc6c312..e591758c21 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1695,13 +1695,15 @@ str_tolower(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strlower(dst, dstsize, src, srclen, false);
+ needed = unicode_strlower(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1843,13 +1845,15 @@ str_toupper(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
if (needed + 1 > dstsize)
{
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strupper(dst, dstsize, src, srclen, false);
+ needed = unicode_strupper(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full);
Assert(needed + 1 == dstsize);
}
@@ -1929,6 +1933,7 @@ struct WordBoundaryState
size_t offset;
bool init;
bool prev_alnum;
+ bool posix;
};
/*
@@ -1945,7 +1950,7 @@ initcap_wbnext(void *state)
{
pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
- bool curr_alnum = pg_u_isalnum(u, true);
+ bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
if (!wbstate->init || curr_alnum != wbstate->prev_alnum)
{
@@ -2032,6 +2037,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
.offset = 0,
.init = false,
.prev_alnum = false,
+ .posix = !mylocale->info.builtin.casemap_full,
};
Assert(GetDatabaseEncoding() == PG_UTF8);
@@ -2040,7 +2046,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
dstsize = srclen + 1;
dst = palloc(dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
if (needed + 1 > dstsize)
{
@@ -2051,7 +2058,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid)
/* grow buffer if needed and retry */
dstsize = needed + 1;
dst = repalloc(dst, dstsize);
- needed = unicode_strtitle(dst, dstsize, src, srclen, false,
+ needed = unicode_strtitle(dst, dstsize, src, srclen,
+ mylocale->info.builtin.casemap_full,
initcap_wbnext, &wbstate);
Assert(needed + 1 == dstsize);
}
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 377f5837a0..b6c96a6c39 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -1596,6 +1596,7 @@ pg_newlocale_from_collation(Oid collid)
result.info.builtin.locale = MemoryContextStrdup(TopMemoryContext,
locstr);
+ result.info.builtin.casemap_full = (strcmp(locstr, "PG_UNICODE_FAST") == 0);
}
else if (collform->collprovider == COLLPROVIDER_LIBC)
{
@@ -1743,6 +1744,8 @@ get_collation_actual_version(char collprovider, const char *collcollate)
return "1";
else if (strcmp(collcollate, "C.UTF-8") == 0)
return "1";
+ else if (strcmp(collcollate, "PG_UNICODE_FAST") == 0)
+ return "1";
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -2528,9 +2531,12 @@ builtin_locale_encoding(const char *locale)
{
if (strcmp(locale, "C") == 0)
return -1;
- if (strcmp(locale, "C.UTF-8") == 0)
+ else if (strcmp(locale, "C.UTF-8") == 0)
+ return PG_UTF8;
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
return PG_UTF8;
+
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("invalid locale name \"%s\" for builtin provider",
@@ -2557,6 +2563,8 @@ builtin_validate_locale(int encoding, const char *locale)
canonical_name = "C";
else if (strcmp(locale, "C.UTF-8") == 0 || strcmp(locale, "C.UTF8") == 0)
canonical_name = "C.UTF-8";
+ else if (strcmp(locale, "PG_UNICODE_FAST") == 0)
+ canonical_name = "PG_UNICODE_FAST";
if (!canonical_name)
ereport(ERROR,
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 0805398e24..9a357e3f90 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -432,6 +432,7 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
default_locale.info.builtin.locale = MemoryContextStrdup(
TopMemoryContext, datlocale);
+ default_locale.info.builtin.casemap_full = (strcmp(datlocale, "PG_UNICODE_FAST") == 0);
}
else if (dbform->datlocprovider == COLLPROVIDER_ICU)
{
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 30e17bd1d1..262a984d04 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2408,6 +2408,8 @@ setlocales(void)
else if (strcmp(datlocale, "C.UTF-8") == 0 ||
strcmp(datlocale, "C.UTF8") == 0)
canonname = "C.UTF-8";
+ else if (strcmp(datlocale, "PG_UNICODE_FAST") == 0)
+ canonname = "PG_UNICODE_FAST";
else
pg_fatal("invalid locale name \"%s\" for builtin provider",
datlocale);
@@ -2704,7 +2706,9 @@ setup_locale_encoding(void)
if (locale_provider == COLLPROVIDER_BUILTIN)
{
- if (strcmp(datlocale, "C.UTF-8") == 0 && encodingid != PG_UTF8)
+ if ((strcmp(datlocale, "C.UTF-8") == 0 ||
+ strcmp(datlocale, "PG_UNICODE_FAST") == 0) &&
+ encodingid != PG_UTF8)
pg_fatal("builtin provider locale \"%s\" requires encoding \"%s\"",
datlocale, "UTF-8");
}
diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat
index dcf554bbd5..82a2fc582d 100644
--- a/src/include/catalog/pg_collation.dat
+++ b/src/include/catalog/pg_collation.dat
@@ -33,5 +33,8 @@
{ oid => '811', descr => 'sorts by Unicode code point; Unicode and POSIX character semantics',
collname => 'pg_c_utf8', collprovider => 'b', collencoding => '6',
colllocale => 'C.UTF-8', collversion => '1' },
+{ oid => '812', descr => 'sorts by Unicode code point; Unicode character semantics',
+ collname => 'pg_unicode_fast', collprovider => 'b', collencoding => '6',
+ colllocale => 'PG_UNICODE_FAST', collversion => '1' },
]
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 205aa20067..03890000db 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -79,6 +79,7 @@ struct pg_locale_struct
struct
{
const char *locale;
+ bool casemap_full;
} builtin;
locale_t lt;
#ifdef USE_ICU
diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out
index eff0ef21ac..63327a8fdd 100644
--- a/src/test/regress/expected/collate.utf8.out
+++ b/src/test/regress/expected/collate.utf8.out
@@ -134,3 +134,163 @@ SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
t
(1 row)
+--
+-- Test PG_UNICODE_FAST
+--
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+ERROR: invalid locale name "unicode" for builtin provider
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+ t | lower | initcap | upper | t_bytes | lower_t_bytes | initcap_t_bytes | upper_t_bytes
+-----------------+-----------------+------------------+-------------------+---------+---------------+-----------------+---------------
+ abc DEF 123abc | abc def 123abc | Abc Def 123Abc | ABC DEF 123ABC | 14 | 14 | 14 | 14
+ ábc sßs ßss DÉF | ábc sßs ßss déf | Ábc Sßs Ssss Déf | ÁBC SSSS SSSS DÉF | 19 | 19 | 19 | 19
+ DŽxxDŽ džxxDž Džxxdž | džxxdž džxxdž džxxdž | Džxxdž Džxxdž Džxxdž | DŽXXDŽ DŽXXDŽ DŽXXDŽ | 20 | 20 | 20 | 20
+ ȺȺȺ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 6 | 9 | 8 | 6
+ ⱥⱥⱥ | ⱥⱥⱥ | Ⱥⱥⱥ | ȺȺȺ | 9 | 9 | 8 | 6
+ ⱥȺ | ⱥⱥ | Ⱥⱥ | ȺȺ | 5 | 6 | 5 | 4
+(6 rows)
+
+DROP TABLE test_pg_unicode_fast;
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+ lower
+-------
+ ας
+(1 row)
+
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+ lower
+-------
+ ας0
+(1 row)
+
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+ lower
+-------
+ ἀς̓
+(1 row)
+
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+ lower
+-------
+ ᾳςͅ
+(1 row)
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+ lower
+-------
+ σ
+(1 row)
+
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+ lower
+-------
+ 0σ
+(1 row)
+
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+ lower
+-------
+ ασα
+(1 row)
+
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+ lower
+-------
+ ἀσ̓α
+(1 row)
+
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+ lower
+-------
+ ᾳσͅα
+(1 row)
+
+-- properties
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+-- case mapping
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql
index 1f5f9ef491..c63928d38e 100644
--- a/src/test/regress/sql/collate.utf8.sql
+++ b/src/test/regress/sql/collate.utf8.sql
@@ -65,3 +65,63 @@ SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8;
SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8;
SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8;
SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; -- same as above with cases reversed
+
+--
+-- Test PG_UNICODE_FAST
+--
+
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'unicode'); -- fails
+CREATE COLLATION regress_pg_unicode_fast (
+ provider = builtin, locale = 'PG_UNICODE_FAST');
+
+CREATE TABLE test_pg_unicode_fast (
+ t TEXT COLLATE PG_UNICODE_FAST
+);
+INSERT INTO test_pg_unicode_fast VALUES
+ ('abc DEF 123abc'),
+ ('ábc sßs ßss DÉF'),
+ ('DŽxxDŽ džxxDž Džxxdž'),
+ ('ȺȺȺ'),
+ ('ⱥⱥⱥ'),
+ ('ⱥȺ');
+
+SELECT
+ t, lower(t), initcap(t), upper(t),
+ length(convert_to(t, 'UTF8')) AS t_bytes,
+ length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes,
+ length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes,
+ length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes
+ FROM test_pg_unicode_fast;
+
+DROP TABLE test_pg_unicode_fast;
+
+-- test Final_Sigma
+SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); -- 0391 03A3
+SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0030
+SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343
+SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345
+
+-- test !Final_Sigma
+SELECT lower('Σ' COLLATE PG_UNICODE_FAST); -- 03A3
+SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); -- 0030 03A3
+SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); -- 0391 03A3 0391
+SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); -- 0391 0343 03A3 0343 0391
+SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); -- 0391 0345 03A3 0345 0391
+
+-- properties
+
+SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST;
+SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST;
+SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; -- symbols are not punctuation
+SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST;
+SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST;
+
+-- case mapping
+
+SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST;
+SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST;
+SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST;
+SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; -- same as above with cases reversed
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-26 07:04 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-04-01 19:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-04-04 12:05 ` Peter Eisentraut <[email protected]>
2024-04-04 22:22 ` Re: Built-in CTYPE provider Thomas Munro <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-04-04 12:05 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 01.04.24 21:52, Jeff Davis wrote:
> On Tue, 2024-03-26 at 08:04 +0100, Peter Eisentraut wrote:
>> The patch set v27 is ok with me, modulo (a) discussion about initcap
>> semantics, and (b) what collation to assign to ucs_basic, which can
>> be
>> revisited later.
>
> Attached v28.
>
> The remaining patches are for full case mapping and PG_UNICODE_FAST.
>
> I am fine waiting until July to get these remaining patches committed.
> That would give us time to sort out details like:
>
> * Get consensus that it's OK to change UCS_BASIC.
> * Figure out if we need a pg-specific locale and whether
> PG_UNICODE_FAST is the right name.
> * Make sure that full case mapping interacts with regexes in a sane way
> (probably it needs to just fall back to simple case mapping, but
> perhaps that's worth a discussion).
> * Implement case folding.
> * Implement a more unicode-friendly TITLECASE() function, which could
> offer a number of options that don't fit well with INITCAP().
> * Figure out if UPPER()/LOWER() should also have some of those options.
>
> Thoughts?
Yeah, I think it's good to give some more time to work out these things.
The features committed for PG17 so far are solid, so it's a good point
to pause.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-26 07:04 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-04-01 19:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-04-04 12:05 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-04-04 22:22 ` Thomas Munro <[email protected]>
2024-04-04 23:38 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
0 siblings, 1 reply; 94+ messages in thread
From: Thomas Munro @ 2024-04-04 22:22 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
Hi,
+command_ok(
+ [
+ 'initdb', '--no-sync',
+ '--locale-provider=builtin', '-E UTF-8',
+ '--builtin-locale=C.UTF-8', "$tempdir/data8"
+ ],
+ 'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
This Sun animal recently turned on --enable-tap-tests, and that ↑ failed[1]:
# Running: initdb --no-sync --locale-provider=builtin -E UTF-8
--builtin-locale=C.UTF-8
/home/marcel/build-farm-15/buildroot/HEAD/pgsql.build/src/bin/initdb/tmp_check/tmp_test_XvK1/data8
The files belonging to this database system will be owned by user "marcel".
This user must also own the server process.
The database cluster will be initialized with this locale configuration:
locale provider: builtin
default collation: C.UTF-8
LC_COLLATE: en_US
LC_CTYPE: en_US
LC_MESSAGES: C
LC_MONETARY: en_US
LC_NUMERIC: en_US
LC_TIME: en_US
initdb: error: encoding mismatch
initdb: detail: The encoding you selected (UTF8) and the encoding that
the selected locale uses (LATIN1) do not match. This would lead to
misbehavior in various character string processing functions.
initdb: hint: Rerun initdb and either do not specify an encoding
explicitly, or choose a matching combination.
[14:04:12.462](0.036s) not ok 28 - locale provider builtin with -E
UTF-8 --builtin-locale=C.UTF-8
[1] https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=margay&dt=2024-04-04%2011%3A42%3A40
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-26 07:04 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-04-01 19:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-04-04 12:05 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-04-04 22:22 ` Re: Built-in CTYPE provider Thomas Munro <[email protected]>
@ 2024-04-04 23:38 ` Jeff Davis <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Jeff Davis @ 2024-04-04 23:38 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; Peter Eisentraut <[email protected]>; +Cc: Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Fri, 2024-04-05 at 11:22 +1300, Thomas Munro wrote:
> Hi,
>
> +command_ok(
> + [
> + 'initdb', '--no-sync',
> + '--locale-provider=builtin', '-E UTF-8',
> + '--builtin-locale=C.UTF-8', "$tempdir/data8"
> + ],
> + 'locale provider builtin with -E UTF-8 --builtin-
> locale=C.UTF-8');
...
> LC_COLLATE: en_US
> LC_CTYPE: en_US
> LC_MESSAGES: C
> LC_MONETARY: en_US
> LC_NUMERIC: en_US
> LC_TIME: en_US
> initdb: error: encoding mismatch
> initdb: detail: The encoding you selected (UTF8) and the encoding
> that
> the selected locale uses (LATIN1) do not match.
Thank you for the report.
I fixed it in e2a2357671 by forcing the environment locale to C which
is compatible with any encoding. The test still forces the encoding to
UTF-8 and the collation to the builtin C.UTF-8.
In passing, I noticed some unrelated regression test failures when I
set LANG=tr_TR: tsearch, tsdict, json, and jsonb. There's an additional
failure in the updatable_views test when LANG=tr_TR.utf8. I haven't
looked into the details yet.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v1-0001-Fix-test-failure-in-001_initdb.pl.patch (1.1K, ../../[email protected]/2-v1-0001-Fix-test-failure-in-001_initdb.pl.patch)
download | inline diff:
From a7bf58f27bcd60bf79c097c7f462fa183264e9cd Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Thu, 4 Apr 2024 15:55:03 -0700
Subject: [PATCH v1] Fix test failure in 001_initdb.pl.
Reported-by: Thomas Munro
Discussion: https://postgr.es/m/CA+hUKGK-ZqV1njkG_=xcCqXh2fcMkz85FTMnhS2opm4ZerH=xw@mail.gmail.com
---
src/bin/initdb/t/001_initdb.pl | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index c63d3206d9..b31dad2464 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -200,6 +200,7 @@ command_ok(
[
'initdb', '--no-sync',
'--locale-provider=builtin', '-E UTF-8',
+ '--lc-collate=C', '--lc-ctype=C',
'--builtin-locale=C.UTF-8', "$tempdir/data8"
],
'locale provider builtin with -E UTF-8 --builtin-locale=C.UTF-8');
@@ -208,6 +209,7 @@ command_fails(
[
'initdb', '--no-sync',
'--locale-provider=builtin', '-E SQL_ASCII',
+ '--lc-collate=C', '--lc-ctype=C',
'--builtin-locale=C.UTF-8', "$tempdir/data9"
],
'locale provider builtin with --builtin-locale=C.UTF-8 fails for SQL_ASCII'
--
2.34.1
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-27 15:53 ` Daniel Verite <[email protected]>
4 siblings, 0 replies; 94+ messages in thread
From: Daniel Verite @ 2024-03-27 15:53 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
Jeff Davis wrote:
> The tests include initcap('123abc') which is '123abc' in the PG_C_UTF8
> collation vs '123Abc' in PG_UNICODE_FAST.
>
> The reason for the latter behavior is that the Unicode Default Case
> Conversion algorithm for toTitlecase() advances to the next Cased
> character before mapping to titlecase, and digits are not Cased. ICU
> has a configurable adjustment, and defaults in a way that produces
> '123abc'.
Even aside from ICU, there's a different behavior between glibc
and pg_c_utf8 glibc for codepoints in the decimal digit category
outside of the US-ASCII range '0'..'9',
select initcap(concat(chr(0xff11), 'a') collate "C.utf8"); -- glibc 2.35
initcap
---------
1a
select initcap(concat(chr(0xff11), 'a') collate "pg_c_utf8");
initcap
---------
1A
Both collations consider that chr(0xff11) is not a digit
(isdigit()=>false) but C.utf8 says that it's alpha, whereas pg_c_utf8
says it's neither digit nor alpha.
AFAIU this is why in the above initcap() call, pg_c_utf8 considers
that 'a' is the first alphanumeric, whereas C.utf8 considers that '1'
is the first alphanumeric, leading to different capitalizations.
Comparing the 3 providers:
WITH v(provider,type,result) AS (values
('ICU', 'isalpha', chr(0xff11) ~ '[[:alpha:]]' collate "unicode"),
('glibc', 'isalpha', chr(0xff11) ~ '[[:alpha:]]' collate "C.utf8"),
('builtin', 'isalpha', chr(0xff11) ~ '[[:alpha:]]' collate "pg_c_utf8"),
('ICU', 'isdigit', chr(0xff11) ~ '[[:digit:]]' collate "unicode"),
('glibc', 'isdigit', chr(0xff11) ~ '[[:digit:]]' collate "C.utf8"),
('builtin', 'isdigit', chr(0xff11) ~ '[[:digit:]]' collate "pg_c_utf8")
)
select * from v
\crosstabview
provider | isalpha | isdigit
----------+---------+---------
ICU | f | t
glibc | t | f
builtin | f | f
Are we fine with pg_c_utf8 differing from both ICU's point of view
(U+ff11 is digit and not alpha) and glibc point of view (U+ff11 is not
digit, but it's alpha)?
Aside from initcap(), this is going to be significant for regular
expressions.
Best regards,
--
Daniel Vérité
https://postgresql.verite.pro/
Twitter: @DanielVerite
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-06-29 22:08 ` Noah Misch <[email protected]>
2024-07-01 19:24 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
4 siblings, 1 reply; 94+ messages in thread
From: Noah Misch @ 2024-06-29 22:08 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Wed, Mar 20, 2024 at 05:13:26PM -0700, Jeff Davis wrote:
> On Tue, 2024-03-19 at 13:41 +0100, Peter Eisentraut wrote:
> > * v25-0002-Support-C.UTF-8-locale-in-the-new-builtin-collat.patch
> >
> > Looks ok.
>
> Committed.
> <varlistentry>
> + <term><literal>pg_c_utf8</literal></term>
> + <listitem>
> + <para>
> + This collation sorts by Unicode code point values rather than natural
> + language order. For the functions <function>lower</function>,
> + <function>initcap</function>, and <function>upper</function>, it uses
> + Unicode simple case mapping. For pattern matching (including regular
> + expressions), it uses the POSIX Compatible variant of Unicode <ulink
> + url="https://www.unicode.org/reports/tr18/#Compatibility_Properties">Compatibility
> + Properties</ulink>. Behavior is efficient and stable within a
> + <productname>Postgres</productname> major version. This collation is
> + only available for encoding <literal>UTF8</literal>.
> + </para>
> + </listitem>
> + </varlistentry>
lower(), initcap(), upper(), and regexp_matches() are PROVOLATILE_IMMUTABLE.
Until now, we've delegated that responsibility to the user. The user is
supposed to somehow never update libc or ICU in a way that changes outcomes
from these functions. Now that postgresql.org is taking that responsibility
for builtin C.UTF-8, how should we govern it? I think the above text and [1]
convey that we'll update the Unicode data between major versions, making
functions like lower() effectively STABLE. Is that right?
(This thread had some discussion[2] that datcollversion/collversion won't
necessarily change when a major versions changes lower() behavior.)
[1] https://postgr.es/m/[email protected]
[2] https://postgr.es/m/[email protected]
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-06-29 22:08 ` Re: Built-in CTYPE provider Noah Misch <[email protected]>
@ 2024-07-01 19:24 ` Jeff Davis <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Jeff Davis @ 2024-07-01 19:24 UTC (permalink / raw)
To: Noah Misch <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Sat, 2024-06-29 at 15:08 -0700, Noah Misch wrote:
> lower(), initcap(), upper(), and regexp_matches() are
> PROVOLATILE_IMMUTABLE.
> Until now, we've delegated that responsibility to the user. The user
> is
> supposed to somehow never update libc or ICU in a way that changes
> outcomes
> from these functions.
To me, "delegated" connotes a clear and organized transfer of
responsibility to the right person to solve it. In that sense, I
disagree that we've delegated it.
What's happened here is evolution of various choices that seemed
reasonable at the time. Unfortunately, the consequences that are hard
for us to manage and even harder for users to manage themselves.
> Now that postgresql.org is taking that responsibility
> for builtin C.UTF-8, how should we govern it? I think the above text
> and [1]
> convey that we'll update the Unicode data between major versions,
> making
> functions like lower() effectively STABLE. Is that right?
Marking them STABLE is not a viable option, that would break a lot of
valid use cases, e.g. an index on LOWER().
Unicode already has its own governance, including a stability policy
that includes case mapping:
https://www.unicode.org/policies/stability_policy.html#Case_Pair
Granted, that policy does not guarantee that the results will never
change. In particular, the results can change if using unassinged code
poitns that are later assigned to Cased characters.
That's not terribly common though; for instance, there are zero changes
in uppercase/lowercase behavior between Unicode 14.0 (2021) and 15.1
(current) -- even for code points that were unassigned in 14.0 and
later assigned. I checked this by modifying case_test.c to look at
unassigned code points as well.
There's a greater chance that character properties can change (e.g.
whether a character is "alphabetic" or not) in new releases of Unicode.
Such properties can affect regex character classifications, and in some
cases the results of initcap (because it uses the "alphanumeric"
classification to determine word boundaries).
I don't think we need code changes for 17. Some documentation changes
might be helpful, though. Should we have a note around LOWER()/UPPER()
that users should REINDEX any dependent indexes when the provider is
updated?
> (This thread had some discussion[2] that datcollversion/collversion
> won't
> necessarily change when a major versions changes lower() behavior.)
datcollversion/collversion track the vertsion of the collation
specifically (text ordering only), not the ctype (character semantics).
When using the libc provider, get_collation_actual_version() completely
ignores the ctype.
It would be interesting to consider tracking the versions separately,
though.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
@ 2024-03-14 14:38 ` Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
1 sibling, 1 reply; 94+ messages in thread
From: Peter Eisentraut @ 2024-03-14 14:38 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On 14.03.24 09:08, Jeff Davis wrote:
> 0001 (the C.UTF-8 locale) is also close. Considering that most of the
> infrastructure is already in place, that's not a large patch. You many
> have some comments about the way I'm canonicalizing and validating in
> initdb -- that could be cleaner, but it feels like I should refactor
> the surrounding code separately first.
If have tested this against the libc locale C.utf8 that was available on
the OS, and the behavior is consistent.
I wonder if we should version the builtin locales too. We might make a
mistake and want to change something sometime?
Tiny comments:
* src/bin/scripts/t/020_createdb.pl
The two added tests should have different names that tells them apart
(like the new initdb tests).
* src/include/catalog/pg_collation.dat
Maybe use 'and' instead of '&' in the description.
> 0002 (inlining utf8 functions) is also ready.
Seems ok.
> For 0003 and beyond, I'd like some validation that it's what you had in
> mind.
I'll look into those later.
^ permalink raw reply [nested|flat] 94+ messages in thread
* Re: Built-in CTYPE provider
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 14:38 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
@ 2024-03-14 20:42 ` Jeff Davis <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Jeff Davis @ 2024-03-14 20:42 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; Daniel Verite <[email protected]>; +Cc: Robert Haas <[email protected]>; Jeremy Schneider <[email protected]>; pgsql-hackers
On Thu, 2024-03-14 at 15:38 +0100, Peter Eisentraut wrote:
> On 14.03.24 09:08, Jeff Davis wrote:
> > 0001 (the C.UTF-8 locale) is also close...
>
> If have tested this against the libc locale C.utf8 that was available
> on
> the OS, and the behavior is consistent.
That was the goal, in spirit.
But to clarify: it's not guaranteed that the built-in C.UTF-8 is always
the same as the libc UTF-8, because different implementations do
different things. For instance, I saw significant differences on MacOS.
> I wonder if we should version the builtin locales too. We might make
> a
> mistake and want to change something sometime?
I'm fine with that, see v25-0004 in the reply to your other mail.
The version only tracks sort order, and all of the builtin locales sort
based on memcmp(). But it's possible there are bugs in the
optimizations around memcmp() (e.g. abbreviated keys, or some future
optimization).
> Tiny comments:
>
> * src/bin/scripts/t/020_createdb.pl
>
> The two added tests should have different names that tells them apart
> (like the new initdb tests).
>
> * src/include/catalog/pg_collation.dat
Done in v25-0002 (in reply to your other mail).
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v14 5/8] Row pattern recognition patch (executor).
@ 2024-02-28 13:59 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-02-28 13:59 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1617 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1679 insertions(+), 11 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 62d028379b..c473cbd218 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -673,6 +752,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +858,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +871,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -862,7 +948,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1018,30 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate,
+ winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +1055,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT,
+ winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1076,32 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1151,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP TO
+ * PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1255,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2219,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2392,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2570,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2668,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2862,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2906,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3013,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3375,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3696,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3810,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3895,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3921,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3958,1249 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 095de7741d..c5bd28ce19 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 9c120fc2b7..81e4580b13 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10456,6 +10456,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 444a5f0fd5..15d8ac4c1e 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2477,6 +2477,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2525,6 +2530,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2561,6 +2579,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Thu_Feb_29_09_19_54_2024_640)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v14-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v15 5/8] Row pattern recognition patch (executor).
@ 2024-03-28 10:30 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-03-28 10:30 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1617 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1679 insertions(+), 11 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3221fa1522..9606e7d463 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -673,6 +752,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +858,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +871,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -862,7 +948,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1018,30 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate,
+ winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +1055,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT,
+ winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1076,32 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1151,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP TO
+ * PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1255,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2219,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2392,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2570,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2486,6 +2671,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2862,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2906,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3013,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3375,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3696,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3810,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3895,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3921,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3958,1249 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 07023ee61d..b9d171e327 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10474,6 +10474,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 1774c56ae3..f2322ace6f 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2549,6 +2549,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2597,6 +2602,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2633,6 +2651,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Thu_Mar_28_19_59_25_2024_076)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v15-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v16 5/8] Row pattern recognition patch (executor).
@ 2024-04-12 06:49 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-04-12 06:49 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1617 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1679 insertions(+), 11 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3221fa1522..9606e7d463 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -673,6 +752,7 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool agg_result_isnull;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -778,6 +858,9 @@ eval_windowaggregates(WindowAggState *winstate)
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ *
+ * - if RPR is enabled and skip mode is SKIP TO NEXT ROW,
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,8 +871,11 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ (rpr_is_defined(winstate) &&
+ winstate->rpSkipTo == ST_NEXT_ROW))
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -862,7 +948,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1018,30 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
+ }
+
+ agg_result_isnull = false;
+ /* RPR is defined? */
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the skip mode is SKIP TO PAST LAST ROW and we already know that
+ * current row is a skipped row, we don't need to accumulate rows,
+ * just return NULL. Note that for unamtched row, we need to do
+ * aggregation so that count(*) shows 0, rather than NULL.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ get_reduced_frame_map(winstate,
+ winstate->currentpos) == RF_SKIPPED)
+ agg_result_isnull = true;
}
/*
@@ -930,6 +1055,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT,
+ winstate->aggregatedupto);
+
+ if (agg_result_isnull)
+ break;
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1076,32 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -996,6 +1151,16 @@ next_tuple:
peraggstate,
result, isnull);
+ /*
+ * RPR is defined and we just return NULL because skip mode is SKIP TO
+ * PAST LAST ROW and current row is skipped row.
+ */
+ if (agg_result_isnull)
+ {
+ *isnull = true;
+ *result = (Datum) 0;
+ }
+
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1255,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2219,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2392,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2570,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2486,6 +2671,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2862,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2906,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3013,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3375,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3696,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3810,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3895,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3921,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3958,1249 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 134e3b22fd..5f7fb538f9 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10477,6 +10477,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index fa2f70b7a4..053ad1764c 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2554,6 +2554,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2602,6 +2607,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2638,6 +2656,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Fri_Apr_12_16_09_08_2024_262)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v16-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v17 5/8] Row pattern recognition patch (executor).
@ 2024-04-28 11:00 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-04-28 11:00 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1610 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1671 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3221fa1522..140bb3941e 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -774,10 +853,12 @@ eval_windowaggregates(WindowAggState *winstate)
* transition function, or
* - we have an EXCLUSION clause, or
* - if the new frame doesn't overlap the old one
+ * - if RPR is enabled
*
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,7 +869,8 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ rpr_is_defined(winstate))
{
peraggstate->restart = true;
numaggs_restart++;
@@ -862,7 +944,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1014,14 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
}
/*
@@ -930,6 +1035,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1056,52 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto),
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+
+ /*
+ * Check if current row needs to be skipped due to no match.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_SKIPPED &&
+ winstate->aggregatedupto == winstate->aggregatedbase)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "skip current row for aggregation");
+#endif
+ break;
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -995,7 +1150,6 @@ next_tuple:
&winstate->perfunc[wfuncno],
peraggstate,
result, isnull);
-
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1244,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2208,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2381,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2559,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2486,6 +2660,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2851,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2895,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3002,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3364,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3685,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3799,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3884,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3910,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3947,1251 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * -----------------
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ * -----------------
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 134e3b22fd..5f7fb538f9 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10477,6 +10477,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index d927ac44a8..971d8682b1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2550,6 +2550,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2598,6 +2603,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2634,6 +2652,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Sun_Apr_28_20_28_26_2024_444)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v17-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v18 5/8] Row pattern recognition patch (executor).
@ 2024-05-11 07:11 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-05-11 07:11 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1610 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1671 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3221fa1522..140bb3941e 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -774,10 +853,12 @@ eval_windowaggregates(WindowAggState *winstate)
* transition function, or
* - we have an EXCLUSION clause, or
* - if the new frame doesn't overlap the old one
+ * - if RPR is enabled
*
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,7 +869,8 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ rpr_is_defined(winstate))
{
peraggstate->restart = true;
numaggs_restart++;
@@ -862,7 +944,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1014,14 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
}
/*
@@ -930,6 +1035,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1056,52 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto),
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+
+ /*
+ * Check if current row needs to be skipped due to no match.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_SKIPPED &&
+ winstate->aggregatedupto == winstate->aggregatedbase)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "skip current row for aggregation");
+#endif
+ break;
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -995,7 +1150,6 @@ next_tuple:
&winstate->perfunc[wfuncno],
peraggstate,
result, isnull);
-
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1244,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2208,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2381,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2559,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2486,6 +2660,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2851,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2895,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3002,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3364,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3685,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3799,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3884,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3910,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3947,1251 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * -----------------
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ * -----------------
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 134e3b22fd..5f7fb538f9 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10477,6 +10477,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 8bc421e7c0..4dd9a17eca 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2554,6 +2554,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2602,6 +2607,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2638,6 +2656,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Sat_May_11_16_23_07_2024_789)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v18-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v19 5/8] Row pattern recognition patch (executor).
@ 2024-05-14 23:26 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-05-14 23:26 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1610 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1671 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3221fa1522..140bb3941e 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -774,10 +853,12 @@ eval_windowaggregates(WindowAggState *winstate)
* transition function, or
* - we have an EXCLUSION clause, or
* - if the new frame doesn't overlap the old one
+ * - if RPR is enabled
*
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,7 +869,8 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ rpr_is_defined(winstate))
{
peraggstate->restart = true;
numaggs_restart++;
@@ -862,7 +944,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1014,14 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
}
/*
@@ -930,6 +1035,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1056,52 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto),
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+
+ /*
+ * Check if current row needs to be skipped due to no match.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_SKIPPED &&
+ winstate->aggregatedupto == winstate->aggregatedbase)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "skip current row for aggregation");
+#endif
+ break;
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -995,7 +1150,6 @@ next_tuple:
&winstate->perfunc[wfuncno],
peraggstate,
result, isnull);
-
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1244,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2208,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2381,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2559,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2486,6 +2660,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2851,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2895,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3002,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3364,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3685,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3799,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3884,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3910,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3947,1251 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * -----------------
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ * -----------------
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 2a9f2105b1..595ef7502e 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10479,6 +10479,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 8bc421e7c0..4dd9a17eca 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2554,6 +2554,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2602,6 +2607,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2638,6 +2656,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Wed_May_15_09_02_03_2024_008)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v19-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v20 5/8] Row pattern recognition patch (executor).
@ 2024-05-24 02:26 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-05-24 02:26 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1610 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1671 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3221fa1522..140bb3941e 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -774,10 +853,12 @@ eval_windowaggregates(WindowAggState *winstate)
* transition function, or
* - we have an EXCLUSION clause, or
* - if the new frame doesn't overlap the old one
+ * - if RPR is enabled
*
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,7 +869,8 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ rpr_is_defined(winstate))
{
peraggstate->restart = true;
numaggs_restart++;
@@ -862,7 +944,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1014,14 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
}
/*
@@ -930,6 +1035,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1056,52 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto),
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+
+ /*
+ * Check if current row needs to be skipped due to no match.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_SKIPPED &&
+ winstate->aggregatedupto == winstate->aggregatedbase)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "skip current row for aggregation");
+#endif
+ break;
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -995,7 +1150,6 @@ next_tuple:
&winstate->perfunc[wfuncno],
peraggstate,
result, isnull);
-
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1244,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2208,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2381,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2559,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2486,6 +2660,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2851,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2895,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3002,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3364,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3685,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3799,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3884,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3910,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3947,1251 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * -----------------
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ * -----------------
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6a5476d3c4..5e7506dabb 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10479,6 +10479,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 8bc421e7c0..4dd9a17eca 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2554,6 +2554,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2602,6 +2607,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2638,6 +2656,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Fri_May_24_11_39_19_2024_763)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v20-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v21 5/8] Row pattern recognition patch (executor).
@ 2024-08-26 04:32 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-08-26 04:32 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1610 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1671 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 3221fa1522..140bb3941e 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -774,10 +853,12 @@ eval_windowaggregates(WindowAggState *winstate)
* transition function, or
* - we have an EXCLUSION clause, or
* - if the new frame doesn't overlap the old one
+ * - if RPR is enabled
*
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,7 +869,8 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ rpr_is_defined(winstate))
{
peraggstate->restart = true;
numaggs_restart++;
@@ -862,7 +944,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1014,14 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
}
/*
@@ -930,6 +1035,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1056,52 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto),
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+
+ /*
+ * Check if current row needs to be skipped due to no match.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_SKIPPED &&
+ winstate->aggregatedupto == winstate->aggregatedbase)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "skip current row for aggregation");
+#endif
+ break;
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -995,7 +1150,6 @@ next_tuple:
&winstate->perfunc[wfuncno],
peraggstate,
result, isnull);
-
/*
* save the result in case next row shares the same frame.
*
@@ -1090,6 +1244,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2053,6 +2208,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2221,6 +2381,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2388,6 +2559,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2486,6 +2660,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2851,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2895,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2723,6 +3002,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3083,7 +3364,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3403,14 +3685,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3477,11 +3799,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3548,6 +3884,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3566,15 +3910,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3605,3 +3947,1251 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * -----------------
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ * -----------------
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 4abc6d9526..c3fafed291 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10549,6 +10549,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index af7d8fd1e7..609b066845 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2578,6 +2578,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2626,6 +2631,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2662,6 +2680,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Mon_Aug_26_13_39_47_2024_878)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v21-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
* [PATCH v22 5/8] Row pattern recognition patch (executor).
@ 2024-09-19 04:48 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 94+ messages in thread
From: Tatsuo Ishii @ 2024-09-19 04:48 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 1610 +++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 37 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 30 +
4 files changed, 1671 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 51a6708a39..e46a3dd1b7 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData
bool restart; /* need to restart this agg in this cycle? */
} WindowStatePerAggData;
+/*
+ * Set of StringInfo. Used in RPR.
+ */
+typedef struct StringSet
+{
+ StringInfo *str_set;
+ Size set_size; /* current array allocation size in number of
+ * items */
+ int set_index; /* current used size */
+} StringSet;
+
+/*
+ * Allowed subsequent PATTERN variables positions.
+ * Used in RPR.
+ *
+ * pos represents the pattern variable defined order in DEFINE caluase. For
+ * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP"
+ * will create:
+ * VariablePos[0].pos[0] = 0; START
+ * VariablePos[1].pos[0] = 1; UP
+ * VariablePos[1].pos[1] = 3; UP
+ * VariablePos[2].pos[0] = 2; DOWN
+ *
+ * Note that UP has two pos because UP appears in PATTERN twice.
+ *
+ * By using this strucrture, we can know which pattern variable can be followed
+ * by which pattern variable(s). For example, START can be followed by UP and
+ * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2.
+ * DOWN can be followed by UP since UP's pos is either 1 or 3.
+ *
+ */
+#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */
+typedef struct VariablePos
+{
+ int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */
+} VariablePos;
+
static void initialize_windowaggregate(WindowAggState *winstate,
WindowStatePerFunc perfuncstate,
WindowStatePerAgg peraggstate);
@@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate);
static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
+
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
static bool window_gettupleslot(WindowObject winobj, int64 pos,
TupleTableSlot *slot);
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+static bool rpr_is_defined(WindowAggState *winstate);
+
+static void create_reduced_frame_map(WindowAggState *winstate);
+static int get_reduced_frame_map(WindowAggState *winstate, int64 pos);
+static void register_reduced_frame_map(WindowAggState *winstate, int64 pos,
+ int val);
+static void clear_reduced_frame_map(WindowAggState *winstate);
+static void update_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringSet * str_set,
+ VariablePos * variable_pos);
+static char pattern_initial(WindowAggState *winstate, char *vname);
+static int do_pattern_match(char *pattern, char *encoded_str);
+
+static StringSet * string_set_init(void);
+static void string_set_add(StringSet * string_set, StringInfo str);
+static StringInfo string_set_get(StringSet * string_set, int index);
+static int string_set_get_size(StringSet * string_set);
+static void string_set_discard(StringSet * string_set);
+static VariablePos * variable_pos_init(void);
+static void variable_pos_register(VariablePos * variable_pos, char initial,
+ int pos);
+static bool variable_pos_compare(VariablePos * variable_pos,
+ char initial1, char initial2);
+static int variable_pos_fetch(VariablePos * variable_pos, char initial,
+ int index);
+static void variable_pos_discard(VariablePos * variable_pos);
/*
* initialize_windowaggregate
@@ -774,10 +853,12 @@ eval_windowaggregates(WindowAggState *winstate)
* transition function, or
* - we have an EXCLUSION clause, or
* - if the new frame doesn't overlap the old one
+ * - if RPR is enabled
*
* Note that we don't strictly need to restart in the last case, but if
* we're going to remove all rows from the aggregation anyway, a restart
* surely is faster.
+ * we restart aggregation too.
*----------
*/
numaggs_restart = 0;
@@ -788,7 +869,8 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->aggregatedbase != winstate->frameheadpos &&
!OidIsValid(peraggstate->invtransfn_oid)) ||
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
- winstate->aggregatedupto <= winstate->frameheadpos)
+ winstate->aggregatedupto <= winstate->frameheadpos ||
+ rpr_is_defined(winstate))
{
peraggstate->restart = true;
numaggs_restart++;
@@ -862,7 +944,22 @@ eval_windowaggregates(WindowAggState *winstate)
* head, so that tuplestore can discard unnecessary rows.
*/
if (agg_winobj->markptr >= 0)
- WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+ {
+ int64 markpos = winstate->frameheadpos;
+
+ if (rpr_is_defined(winstate))
+ {
+ /*
+ * If RPR is used, it is possible PREV wants to look at the
+ * previous row. So the mark pos should be frameheadpos - 1
+ * unless it is below 0.
+ */
+ markpos -= 1;
+ if (markpos < 0)
+ markpos = 0;
+ }
+ WinSetMarkPosition(agg_winobj, markpos);
+ }
/*
* Now restart the aggregates that require it.
@@ -917,6 +1014,14 @@ eval_windowaggregates(WindowAggState *winstate)
{
winstate->aggregatedupto = winstate->frameheadpos;
ExecClearTuple(agg_row_slot);
+
+ /*
+ * If RPR is defined, we do not use aggregatedupto_nonrestarted. To
+ * avoid assertion failure below, we reset aggregatedupto_nonrestarted
+ * to frameheadpos.
+ */
+ if (rpr_is_defined(winstate))
+ aggregatedupto_nonrestarted = winstate->frameheadpos;
}
/*
@@ -930,6 +1035,12 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
@@ -945,9 +1056,52 @@ eval_windowaggregates(WindowAggState *winstate)
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
break;
+
if (ret == 0)
goto next_tuple;
+ if (rpr_is_defined(winstate))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT,
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto),
+ winstate->aggregatedupto,
+ winstate->aggregatedbase);
+#endif
+ /*
+ * If the row status at currentpos is already decided and current
+ * row status is not decided yet, it means we passed the last
+ * reduced frame. Time to break the loop.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->currentpos) != RF_NOT_DETERMINED &&
+ get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_NOT_DETERMINED)
+ break;
+
+ /*
+ * Otherwise we need to calculate the reduced frame.
+ */
+ ret = row_is_in_reduced_frame(winstate->agg_winobj,
+ winstate->aggregatedupto);
+ if (ret == -1) /* unmatched row */
+ break;
+
+ /*
+ * Check if current row needs to be skipped due to no match.
+ */
+ if (get_reduced_frame_map(winstate,
+ winstate->aggregatedupto) == RF_SKIPPED &&
+ winstate->aggregatedupto == winstate->aggregatedbase)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "skip current row for aggregation");
+#endif
+ break;
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1130,7 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -995,7 +1150,6 @@ next_tuple:
&winstate->perfunc[wfuncno],
peraggstate,
result, isnull);
-
/*
* save the result in case next row shares the same frame.
*
@@ -1199,6 +1353,7 @@ begin_partition(WindowAggState *winstate)
winstate->framehead_valid = false;
winstate->frametail_valid = false;
winstate->grouptail_valid = false;
+ create_reduced_frame_map(winstate);
winstate->spooled_rows = 0;
winstate->currentpos = 0;
winstate->frameheadpos = 0;
@@ -2170,6 +2325,11 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT,
+ winstate->currentpos);
+#endif
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2278,6 +2438,17 @@ ExecWindowAgg(PlanState *pstate)
/* don't evaluate the window functions when we're in pass-through mode */
if (winstate->status == WINDOWAGG_RUN)
{
+ /*
+ * If RPR is defined and skip mode is next row, we need to clear
+ * existing reduced frame info so that we newly calculate the info
+ * starting from current row.
+ */
+ if (rpr_is_defined(winstate))
+ {
+ if (winstate->rpSkipTo == ST_NEXT_ROW)
+ clear_reduced_frame_map(winstate);
+ }
+
/*
* Evaluate true window functions
*/
@@ -2445,6 +2616,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2543,6 +2717,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2724,6 +2908,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "defineVariable name: %s", name);
+#endif
+ winstate->defineVariableList =
+ lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *) expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList =
+ lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2732,6 +2953,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *) node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args",
+ func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible
+ * that arg type is
+ * Const? */
+ var = (Var *) expr;
+
+ if (func->funcid == F_PREV)
+
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+#endif
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2789,6 +3068,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3149,7 +3430,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT,
+ pos, winobj->markpos);
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3469,14 +3751,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3543,11 +3865,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
if (relpos > 0)
goto out_of_frame;
+
+ /*
+ * RPR cares about frame head pos. Need to call
+ * update_frameheadpos
+ */
+ update_frameheadpos(winstate);
+
update_frametailpos(winstate);
abs_pos = winstate->frametailpos - 1 + relpos;
@@ -3614,6 +3950,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj,
+ winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos +
+ num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3632,15 +3976,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3671,3 +4013,1251 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * rpr_is_defined
+ * return true if Row pattern recognition is defined.
+ */
+static
+bool
+rpr_is_defined(WindowAggState *winstate)
+{
+ return winstate->patternVariableList != NIL;
+}
+
+/*
+ * -----------------
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame
+ * according to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows
+ * in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ * -----------------
+ */
+static
+int
+row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ int state;
+ int rtn;
+
+ if (!rpr_is_defined(winstate))
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ rtn = 0;
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ if (state == RF_NOT_DETERMINED)
+ {
+ update_frameheadpos(winstate);
+ update_reduced_frame(winobj, pos);
+ }
+
+ state = get_reduced_frame_map(winstate, pos);
+
+ switch (state)
+ {
+ int64 i;
+ int num_reduced_rows;
+
+ case RF_FRAME_HEAD:
+ num_reduced_rows = 1;
+ for (i = pos + 1;
+ get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++)
+ num_reduced_rows++;
+ rtn = num_reduced_rows;
+ break;
+
+ case RF_SKIPPED:
+ rtn = -2;
+ break;
+
+ case RF_UNMATCHED:
+ rtn = -1;
+ break;
+
+ default:
+ elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT,
+ state, pos);
+ break;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT,
+ rtn, pos);
+#endif
+ return rtn;
+}
+
+#define REDUCED_FRAME_MAP_INIT_SIZE 1024L
+
+/*
+ * create_reduced_frame_map
+ * Create reduced frame map
+ */
+static
+void
+create_reduced_frame_map(WindowAggState *winstate)
+{
+ winstate->reduced_frame_map =
+ MemoryContextAlloc(winstate->partcontext,
+ REDUCED_FRAME_MAP_INIT_SIZE);
+ winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE;
+ clear_reduced_frame_map(winstate);
+}
+
+/*
+ * clear_reduced_frame_map
+ * Clear reduced frame map
+ */
+static
+void
+clear_reduced_frame_map(WindowAggState *winstate)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+ MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED,
+ winstate->alloc_sz);
+}
+
+/*
+ * get_reduced_frame_map
+ * Get reduced frame map specified by pos
+ */
+static
+int
+get_reduced_frame_map(WindowAggState *winstate, int64 pos)
+{
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0 || pos >= winstate->alloc_sz)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ return winstate->reduced_frame_map[pos];
+}
+
+/*
+ * register_reduced_frame_map
+ * Add/replace reduced frame map member at pos.
+ * If there's no enough space, expand the map.
+ */
+static
+void
+register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val)
+{
+ int64 realloc_sz;
+
+ Assert(winstate->reduced_frame_map != NULL);
+
+ if (pos < 0)
+ elog(ERROR, "wrong pos: " INT64_FORMAT, pos);
+
+ if (pos > winstate->alloc_sz - 1)
+ {
+ realloc_sz = winstate->alloc_sz * 2;
+
+ winstate->reduced_frame_map =
+ repalloc(winstate->reduced_frame_map, realloc_sz);
+
+ MemSet(winstate->reduced_frame_map + winstate->alloc_sz,
+ RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz);
+
+ winstate->alloc_sz = realloc_sz;
+ }
+
+ winstate->reduced_frame_map[pos] = val;
+}
+
+/*
+ * update_reduced_frame
+ * Update reduced frame info.
+ */
+static
+void
+update_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1,
+ *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+ StringSet *str_set;
+ int initial_index;
+ VariablePos *variable_pos;
+ bool greedy = false;
+ int64 result_pos,
+ i;
+
+ /*
+ * Set of pattern variables evaluated to true. Each character corresponds
+ * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In
+ * this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+
+ /* initialize pattern variables set */
+ str_set = string_set_init();
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check if the pattern does not include any greedy quantifier. If it does
+ * not, we can just apply the pattern to each row. If it succeeds, we are
+ * done.
+ */
+ foreach(lc1, winstate->patternRegexpList)
+ {
+ char *quantifier = strVal(lfirst(lc1));
+
+ if (*quantifier == '+' || *quantifier == '*')
+ {
+ greedy = true;
+ break;
+ }
+ }
+
+ /*
+ * Non greedy case
+ */
+ if (!greedy)
+ {
+ num_matched_rows = 0;
+
+ foreach(lc1, winstate->patternVariableList)
+ {
+ char *vname = strVal(lfirst(lc1));
+
+ encoded_str = makeStringInfo();
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s",
+ pos, vname);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (!expression_result || result_pos < 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is false or out of frame");
+#endif
+ register_reduced_frame_map(winstate, original_pos,
+ RF_UNMATCHED);
+ return;
+ }
+ /* move to next row */
+ pos++;
+ num_matched_rows++;
+ }
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern matched");
+#endif
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ return;
+ }
+
+ /*
+ * Greedy quantifiers included. Loop over until none of pattern matches or
+ * encounters end of frame.
+ */
+ for (;;)
+ {
+ result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2,
+ winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+#ifdef RPR_DEBUG
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s",
+ pos, vname, quantifier);
+#endif
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname,
+ encoded_str, &expression_result);
+ if (expression_result)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression result is true");
+#endif
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ string_set_add(str_set, encoded_str);
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s",
+ encoded_str->data);
+#endif
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (string_set_get_size(str_set) == 0)
+ {
+ /* no match found in the first row */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ return;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s",
+ pos, encoded_str->data);
+#endif
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ initial_index = 0;
+
+ variable_pos = variable_pos_init();
+
+ forboth(lc1, winstate->patternVariableList,
+ lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+
+ /*
+ * Register the initial at initial_index. If the initial appears more
+ * than once, all of it's initial_index will be recorded. This could
+ * happen if a pattern variable appears in the PATTERN clause more
+ * than once like "UP DOWN UP" "UP UP UP".
+ */
+ variable_pos_register(variable_pos, initial, initial_index);
+
+ initial_index++;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s",
+ pos, pattern_str->data);
+#endif
+
+ /* look for matching pattern variable sequence */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set started");
+#endif
+ num_matched_rows = search_str_set(pattern_str->data,
+ str_set, variable_pos);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "search_str_set returns: %d", num_matched_rows);
+#endif
+ variable_pos_discard(variable_pos);
+ string_set_discard(str_set);
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ if (num_matched_rows <= 0)
+ {
+ /* no match */
+ register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED);
+ }
+ else
+ {
+ register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD);
+
+ for (i = original_pos + 1; i < original_pos + num_matched_rows; i++)
+ {
+ register_reduced_frame_map(winstate, i, RF_SKIPPED);
+ }
+ }
+
+ return;
+}
+
+/*
+ * search_str_set
+ * Perform pattern matching using "pattern" against str_set. pattern is a
+ * regular expression derived from PATTERN clause. Note that the regular
+ * expression string is prefixed by '^' and followed by initials represented
+ * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo
+ * has a string comprising initials of pattern variable strings being true in
+ * a row. The initials are one of [a-y], parallel to the order of variable
+ * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If
+ * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a',
+ * 'b' and 'c'. The "pattern" will be "^ab+c".
+ *
+ * variable_pos is an array representing the order of pattern variable string
+ * initials in PATTERN clause. For example initial 'a' potion is in
+ * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP"
+ * (UP appears twice), then "UP" (initial is 'b') has two position 1 and
+ * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and
+ * variable_pos[1].pos[1] = 3.
+ *
+ * Returns the longest number of the matching rows (greedy matching) if
+ * quatifier '+' or '*' is included in "pattern".
+ */
+static
+int
+search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos)
+{
+#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */
+#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the
+ * char */
+#define DISCARD_CHAR 'z' /* a pattern is not need to keep */
+
+ int set_size; /* number of rows in the set */
+ int resultlen;
+ int index;
+ StringSet *old_str_set,
+ *new_str_set;
+ int new_str_size;
+ int len;
+
+ set_size = string_set_get_size(str_set);
+ new_str_set = string_set_init();
+ len = 0;
+ resultlen = 0;
+
+ /*
+ * Generate all possible pattern variable name initials as a set of
+ * StringInfo named "new_str_set". For example, if we have two rows
+ * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set
+ * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end.
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size);
+#endif
+ for (index = 0; index < set_size; index++)
+ {
+ StringInfo str; /* search target row */
+ char *p;
+ int old_set_size;
+ int i;
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "index: %d", index);
+#endif
+ if (index == 0)
+ {
+ /* copy variables in row 0 */
+ str = string_set_get(str_set, index);
+ p = str->data;
+
+ /*
+ * Loop over each new pattern variable char.
+ */
+ while (*p)
+ {
+ StringInfo new = makeStringInfo();
+
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: NULL new_str: %s", new->data);
+#endif
+ p++; /* next pattern variable */
+ }
+ }
+ else /* index != 0 */
+ {
+ old_str_set = new_str_set;
+ new_str_set = string_set_init();
+ str = string_set_get(str_set, index);
+ old_set_size = string_set_get_size(old_str_set);
+
+ /*
+ * Loop over each rows in the previous result set.
+ */
+ for (i = 0; i < old_set_size; i++)
+ {
+ StringInfo new;
+ char last_old_char;
+ int old_str_len;
+ StringInfo old = string_set_get(old_str_set, i);
+
+ p = old->data;
+ old_str_len = strlen(p);
+ if (old_str_len > 0)
+ last_old_char = p[old_str_len - 1];
+ else
+ last_old_char = '\0';
+
+ /* Is this old set freezed? */
+ if (last_old_char == FREEZED_CHAR)
+ {
+ /* if shorter match. we can discard it */
+ if ((old_str_len - 1) < resultlen)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set because shorter match: %s",
+ old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "keep this old set: %s", old->data);
+#endif
+
+ /* move the old set to new_str_set */
+ string_set_add(new_str_set, old);
+ old_str_set->str_set[i] = NULL;
+ continue;
+ }
+ /* Can this old set be discarded? */
+ else if (last_old_char == DISCARD_CHAR)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this old set: %s", old->data);
+#endif
+ continue;
+ }
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "str->data: %s", str->data);
+#endif
+
+ /*
+ * loop over each pattern variable initial char in the input
+ * set.
+ */
+ for (p = str->data; *p; p++)
+ {
+ /*
+ * Optimization. Check if the row's pattern variable
+ * initial character position is greater than or equal to
+ * the old set's last pattern variable initial character
+ * position. For example, if the old set's last pattern
+ * variable initials are "ab", then the new pattern
+ * variable initial can be "b" or "c" but can not be "a",
+ * if the initials in PATTERN is something like "a b c" or
+ * "a b+ c+" etc. This optimization is possible when we
+ * only allow "+" quantifier.
+ */
+ if (variable_pos_compare(variable_pos, last_old_char, *p))
+ {
+ /* copy source string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add pattern variable char */
+ appendStringInfoChar(new, *p);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s",
+ old->data, new->data);
+#endif
+
+ /*
+ * Adhoc optimization. If the first letter in the
+ * input string is the first and second position one
+ * and there's no associated quatifier '+', then we
+ * can dicard the input because there's no chace to
+ * expand the string further.
+ *
+ * For example, pattern "abc" cannot match "aa".
+ */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c",
+ pattern[1], pattern[2], new->data[0], new->data[1]);
+#endif
+ if (pattern[1] == new->data[0] &&
+ pattern[1] == new->data[1] &&
+ pattern[2] != '+' &&
+ pattern[1] != pattern[2])
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "discard this new data: %s",
+ new->data);
+#endif
+ pfree(new->data);
+ pfree(new);
+ continue;
+ }
+
+ /* add new one to string set */
+ string_set_add(new_str_set, new);
+ }
+ else
+ {
+ /*
+ * We are freezing this pattern string. Since there's
+ * no chance to expand the string further, we perform
+ * pattern matching against the string. If it does not
+ * match, we can discard it.
+ */
+ len = do_pattern_match(pattern, old->data);
+
+ if (len <= 0)
+ {
+ /* no match. we can discard it */
+ continue;
+ }
+
+ else if (len <= resultlen)
+ {
+ /* shorter match. we can discard it */
+ continue;
+ }
+ else
+ {
+ /* match length is the longest so far */
+
+ int new_index;
+
+ /* remember the longest match */
+ resultlen = len;
+
+ /* freeze the pattern string */
+ new = makeStringInfo();
+ enlargeStringInfo(new, old->len + 1);
+ appendStringInfoString(new, old->data);
+ /* add freezed mark */
+ appendStringInfoChar(new, FREEZED_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data);
+#endif
+ string_set_add(new_str_set, new);
+
+ /*
+ * Search new_str_set to find out freezed entries
+ * that have shorter match length. Mark them as
+ * "discard" so that they are discarded in the
+ * next round.
+ */
+
+ /* new_index_size should be the one before */
+ new_str_size =
+ string_set_get_size(new_str_set) - 1;
+
+ /* loop over new_str_set */
+ for (new_index = 0; new_index < new_str_size;
+ new_index++)
+ {
+ char new_last_char;
+ int new_str_len;
+
+ new = string_set_get(new_str_set, new_index);
+ new_str_len = strlen(new->data);
+ if (new_str_len > 0)
+ {
+ new_last_char =
+ new->data[new_str_len - 1];
+ if (new_last_char == FREEZED_CHAR &&
+ (new_str_len - 1) <= len)
+ {
+ /*
+ * mark this set to discard in the
+ * next round
+ */
+ appendStringInfoChar(new, DISCARD_CHAR);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "add discard char: %s", new->data);
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* we no longer need old string set */
+ string_set_discard(old_str_set);
+ }
+ }
+
+ /*
+ * Perform pattern matching to find out the longest match.
+ */
+ new_str_size = string_set_get_size(new_str_set);
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "new_str_size: %d", new_str_size);
+#endif
+ len = 0;
+ resultlen = 0;
+
+ for (index = 0; index < new_str_size; index++)
+ {
+ StringInfo s;
+
+ s = string_set_get(new_str_set, index);
+ if (s == NULL)
+ continue; /* no data */
+
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "target string: %s", s->data);
+#endif
+ len = do_pattern_match(pattern, s->data);
+ if (len > resultlen)
+ {
+ /* remember the longest match */
+ resultlen = len;
+
+ /*
+ * If the size of result set is equal to the number of rows in the
+ * set, we are done because it's not possible that the number of
+ * matching rows exceeds the number of rows in the set.
+ */
+ if (resultlen >= set_size)
+ break;
+ }
+ }
+
+ /* we no longer need new string set */
+ string_set_discard(new_str_set);
+
+ return resultlen;
+}
+
+/*
+ * do_pattern_match
+ * perform pattern match using pattern against encoded_str.
+ * returns matching number of rows if matching is succeeded.
+ * Otherwise returns 0.
+ */
+static
+int
+do_pattern_match(char *pattern, char *encoded_str)
+{
+ Datum d;
+ text *res;
+ char *substr;
+ int len = 0;
+ text *pattern_text,
+ *encoded_str_text;
+
+ pattern_text = cstring_to_text(pattern);
+ encoded_str_text = cstring_to_text(encoded_str);
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how long the matched
+ * string is. That is the number of rows in the reduced window frame. The
+ * reason why we can't call textregexsubstr in the first place is, it
+ * errors out if pattern does not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(
+ regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text))))
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(encoded_str_text),
+ PointerGetDatum(pattern_text));
+ if (d != 0)
+ {
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ pfree(substr);
+ }
+ }
+ pfree(encoded_str_text);
+ pfree(pattern_text);
+
+ return len;
+}
+
+/*
+ * evaluate_pattern
+ * Evaluate expression associated with PATTERN variable vname. current_pos is
+ * relative row position in a frame (starting from 0). If vname is evaluated
+ * to true, initial letters associated with vname is appended to
+ * encode_str. result is out paramater representing the expression evaluation
+ * result is true of false.
+ *---------
+ * Return values are:
+ * >=0: the last match absolute row position
+ * otherwise out of frame.
+ *---------
+ */
+static
+int64
+evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1,
+ *lc2,
+ *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+ TupleTableSlot *slot;
+
+ forthree(lc1, winstate->defineVariableList,
+ lc2, winstate->defineClauseList,
+ lc3, winstate->defineInitial)
+ {
+ char initial; /* initial letter associated with vname */
+ char *name = strVal(lfirst(lc1));
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT,
+ vname, current_pos);
+#endif
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+
+ slot = winstate->temp_slot_1;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->prev_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+ slot = winstate->next_slot;
+ if (slot != winstate->null_slot)
+ ExecClearTuple(slot);
+
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * get_slots
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool
+get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT,
+ current_pos);
+#endif
+ return false;
+ }
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT,
+ current_pos);
+#endif
+ ExecClearTuple(slot);
+ return false;
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT,
+ current_pos - 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+#ifdef RPR_DEBUG
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT,
+ current_pos + 1);
+#endif
+ ExecClearTuple(slot);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * pattern_initial
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char
+pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1,
+ *lc2;
+
+ forboth(lc1, winstate->defineVariableList,
+ lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
+
+/*
+ * string_set_init
+ * Create dynamic set of StringInfo.
+ */
+static
+StringSet * string_set_init(void)
+{
+/* Initial allocation size of str_set */
+#define STRING_SET_ALLOC_SIZE 1024
+
+ StringSet *string_set;
+ Size set_size;
+
+ string_set = palloc0(sizeof(StringSet));
+ string_set->set_index = 0;
+ set_size = STRING_SET_ALLOC_SIZE;
+ string_set->str_set = palloc(set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+
+ return string_set;
+}
+
+/*
+ * string_set_add
+ * Add StringInfo str to StringSet string_set.
+ */
+static
+void
+string_set_add(StringSet * string_set, StringInfo str)
+{
+ Size set_size;
+
+ set_size = string_set->set_size;
+ if (string_set->set_index >= set_size)
+ {
+ set_size *= 2;
+ string_set->str_set = repalloc(string_set->str_set,
+ set_size * sizeof(StringInfo));
+ string_set->set_size = set_size;
+ }
+
+ string_set->str_set[string_set->set_index++] = str;
+
+ return;
+}
+
+/*
+ * string_set_get
+ * Returns StringInfo specified by index.
+ * If there's no data yet, returns NULL.
+ */
+static
+StringInfo
+string_set_get(StringSet * string_set, int index)
+{
+ /* no data? */
+ if (index == 0 && string_set->set_index == 0)
+ return NULL;
+
+ if (index < 0 || index >= string_set->set_index)
+ elog(ERROR, "invalid index: %d", index);
+
+ return string_set->str_set[index];
+}
+
+/*
+ * string_set_get_size
+ * Returns the size of StringSet.
+ */
+static
+int
+string_set_get_size(StringSet * string_set)
+{
+ return string_set->set_index;
+}
+
+/*
+ * string_set_discard
+ * Discard StringSet.
+ * All memory including StringSet itself is freed.
+ */
+static
+void
+string_set_discard(StringSet * string_set)
+{
+ int i;
+
+ for (i = 0; i < string_set->set_index; i++)
+ {
+ StringInfo str = string_set->str_set[i];
+
+ if (str)
+ {
+ pfree(str->data);
+ pfree(str);
+ }
+ }
+ pfree(string_set->str_set);
+ pfree(string_set);
+}
+
+/*
+ * variable_pos_init
+ * Create and initialize variable postion structure
+ */
+static
+VariablePos * variable_pos_init(void)
+{
+ VariablePos *variable_pos;
+
+ variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS);
+ MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS);
+ return variable_pos;
+}
+
+/*
+ * variable_pos_register
+ * Register pattern variable whose initial is initial into postion index.
+ * pos is position of initial.
+ * If pos is already registered, register it at next empty slot.
+ */
+static
+void
+variable_pos_register(VariablePos * variable_pos, char initial, int pos)
+{
+ int index = initial - 'a';
+ int slot;
+ int i;
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ for (i = 0; i < NUM_ALPHABETS; i++)
+ {
+ slot = variable_pos[index].pos[i];
+ if (slot < 0)
+ {
+ /* empty slot found */
+ variable_pos[index].pos[i] = pos;
+ return;
+ }
+ }
+ elog(ERROR, "no empty slot for initial: %c", initial);
+}
+
+/*
+ * variable_pos_compare
+ * Returns true if initial1 can be followed by initial2
+ */
+static
+bool
+variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2)
+{
+ int index1,
+ index2;
+ int pos1,
+ pos2;
+
+ for (index1 = 0;; index1++)
+ {
+ pos1 = variable_pos_fetch(variable_pos, initial1, index1);
+ if (pos1 < 0)
+ break;
+
+ for (index2 = 0;; index2++)
+ {
+ pos2 = variable_pos_fetch(variable_pos, initial2, index2);
+ if (pos2 < 0)
+ break;
+ if (pos1 <= pos2)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * variable_pos_fetch
+ * Fetch position of pattern variable whose initial is initial, and whose index
+ * is index. If no postion was registered by initial, index, returns -1.
+ */
+static
+int
+variable_pos_fetch(VariablePos * variable_pos, char initial, int index)
+{
+ int pos = initial - 'a';
+
+ if (pos < 0 || pos > NUM_ALPHABETS)
+ elog(ERROR, "initial is not valid char: %c", initial);
+
+ if (index < 0 || index > NUM_ALPHABETS)
+ elog(ERROR, "index is not valid: %d", index);
+
+ return variable_pos[pos].pos[index];
+}
+
+/*
+ * variable_pos_discard
+ * Discard VariablePos
+ */
+static
+void
+variable_pos_discard(VariablePos * variable_pos)
+{
+ pfree(variable_pos);
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index 473c61569f..92c528d38c 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/supportnodes.h"
#include "utils/fmgrprotos.h"
@@ -37,11 +40,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 43f608d7a0..6a301920f9 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10604,6 +10604,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 88467977f8..058cef2121 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2581,6 +2581,11 @@ typedef enum WindowAggStatus
* tuples during spool */
} WindowAggStatus;
+#define RF_NOT_DETERMINED 0
+#define RF_FRAME_HEAD 1
+#define RF_SKIPPED 2
+#define RF_UNMATCHED 3
+
typedef struct WindowAggState
{
ScanState ss; /* its first field is NodeTag */
@@ -2640,6 +2645,19 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names
+ * (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions
+ * ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition
+ * variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable
+ * initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2667,6 +2685,18 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /*
+ * Each byte corresponds to a row positioned at absolute its pos in
+ * partition. See above definition for RF_*
+ */
+ char *reduced_frame_map;
+ int64 alloc_sz; /* size of the map */
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Thu_Sep_19_13_59_47_2024_608)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v22-0006-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 94+ messages in thread
end of thread, other threads:[~2024-09-19 04:48 UTC | newest]
Thread overview: 94+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2014-12-25 21:23 POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Alex Shulgin <[email protected]>
2014-12-26 10:41 ` Pavel Stehule <[email protected]>
2014-12-26 10:49 ` Pavel Stehule <[email protected]>
2021-12-18 08:55 ` Damir Belyalov <[email protected]>
2021-12-19 05:09 ` Pavel Stehule <[email protected]>
2022-07-19 12:40 ` Damir Belyalov <[email protected]>
2022-08-15 12:29 ` torikoshia <[email protected]>
2022-08-15 13:23 ` Damir Belyalov <[email protected]>
2022-08-22 12:46 ` torikoshia <[email protected]>
2022-08-24 16:54 ` Damir Belyalov <[email protected]>
2022-08-24 16:57 ` Damir Belyalov <[email protected]>
2022-08-29 13:02 ` torikoshia <[email protected]>
2022-09-21 12:11 ` Damir Belyalov <[email protected]>
2022-09-26 13:04 ` torikoshia <[email protected]>
2022-09-29 13:18 ` Damir Belyalov <[email protected]>
2022-10-17 10:17 ` Damir Belyalov <[email protected]>
2022-11-02 08:46 ` Damir Belyalov <[email protected]>
2022-12-07 11:15 ` Nikita Malakhov <[email protected]>
2022-12-09 14:25 ` Danil Anisimow <[email protected]>
2022-08-24 22:47 Re: POC PATCH: copy from ... exceptions to: (was Re: VLDB Features) Zhihong Yu <[email protected]>
2023-06-25 11:48 [PATCH v1 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-06-26 08:05 [PATCH v2 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-07-26 10:49 [PATCH v3 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-08-09 07:56 [PATCH v4 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-09-02 06:32 [PATCH v5 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-09-12 05:22 [PATCH v6 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-09-22 04:53 [PATCH v7 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-09-25 05:01 [PATCH v8 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-10-04 05:51 [PATCH v9 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-10-22 02:22 [PATCH v10 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-11-08 06:57 [PATCH v11 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2023-12-04 11:23 [PATCH v12 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-01-17 21:01 ` Alexander Korotkov <[email protected]>
2024-01-17 21:06 ` Alexander Korotkov <[email protected]>
2024-01-17 21:37 ` Tom Lane <[email protected]>
2024-01-18 00:56 ` Masahiko Sawada <[email protected]>
2024-01-18 01:10 ` jian he <[email protected]>
2024-01-18 02:15 ` torikoshia <[email protected]>
2024-01-18 07:59 ` Alexander Korotkov <[email protected]>
2024-01-18 08:01 ` Pavel Stehule <[email protected]>
2024-01-18 08:33 ` Masahiko Sawada <[email protected]>
2024-01-18 12:09 ` torikoshia <[email protected]>
2024-01-18 14:59 ` jian he <[email protected]>
2024-01-19 12:37 ` torikoshia <[email protected]>
2024-01-19 13:27 ` Alexander Korotkov <[email protected]>
2024-01-19 14:26 ` torikoshia <[email protected]>
2024-01-22 09:45 [PATCH v13 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-02-13 06:24 Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-02-27 03:01 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-01 05:05 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-02 23:02 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-08 01:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-12 08:24 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-13 07:44 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:08 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 08:54 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-17 21:46 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 17:00 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-18 22:04 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-18 22:48 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-18 22:54 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-19 03:38 ` Re: Built-in CTYPE provider Thomas Munro <[email protected]>
2024-03-19 04:03 ` Re: Built-in CTYPE provider Tom Lane <[email protected]>
2024-03-19 12:41 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-21 00:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-22 14:51 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-22 17:26 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-25 07:29 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-25 17:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-26 07:14 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-24 11:00 ` Re: Built-in CTYPE provider Alexander Lakhin <[email protected]>
2024-03-24 23:41 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-25 07:07 ` Re: Built-in CTYPE provider Laurenz Albe <[email protected]>
2024-03-26 07:04 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-27 22:13 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-04-01 19:52 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-04-04 12:05 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-04-04 22:22 ` Re: Built-in CTYPE provider Thomas Munro <[email protected]>
2024-04-04 23:38 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-27 15:53 ` Re: Built-in CTYPE provider Daniel Verite <[email protected]>
2024-06-29 22:08 ` Re: Built-in CTYPE provider Noah Misch <[email protected]>
2024-07-01 19:24 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-03-14 14:38 ` Re: Built-in CTYPE provider Peter Eisentraut <[email protected]>
2024-03-14 20:42 ` Re: Built-in CTYPE provider Jeff Davis <[email protected]>
2024-02-28 13:59 [PATCH v14 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-03-28 10:30 [PATCH v15 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-04-12 06:49 [PATCH v16 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-04-28 11:00 [PATCH v17 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-05-11 07:11 [PATCH v18 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-05-14 23:26 [PATCH v19 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-05-24 02:26 [PATCH v20 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-08-26 04:32 [PATCH v21 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-09-19 04:48 [PATCH v22 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox