public inbox for [email protected]  
help / color / mirror / Atom feed
From: Jeff Davis <[email protected]>
To: Peter Eisentraut <[email protected]>
To: Daniel Verite <[email protected]>
Cc: Robert Haas <[email protected]>
Cc: Jeremy Schneider <[email protected]>
Cc: [email protected]
Subject: Re: Built-in CTYPE provider
Date: Sat, 02 Mar 2024 15:02:00 -0800
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>

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>&lt;iteration count&gt;</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>&lt;iteration count&gt;</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



view thread (39+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Built-in CTYPE provider
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox